From 08336b39ddeb8eb223ad4fcc82ad4aa0939bf9c0 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 25 Sep 2014 14:38:29 -0700 Subject: [PATCH 01/67] 8059453: javac crashes with -Xjcov and union types Reviewed-by: jlahoda, vromero --- .../com/sun/tools/javac/jvm/CRTable.java | 7 ++++ .../javac/options/XjcovUnionTypeTest.java | 38 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 langtools/test/tools/javac/options/XjcovUnionTypeTest.java diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java index 6c465ca6da2..075913f244a 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java @@ -517,6 +517,13 @@ implements CRTFlags { result = sr; } + @Override + public void visitTypeUnion(JCTypeUnion tree) { + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); + sr.mergeWith(csp(tree.alternatives)); + result = sr; + } + public void visitWildcard(JCWildcard tree) { result = null; } diff --git a/langtools/test/tools/javac/options/XjcovUnionTypeTest.java b/langtools/test/tools/javac/options/XjcovUnionTypeTest.java new file mode 100644 index 00000000000..5c5289c19e4 --- /dev/null +++ b/langtools/test/tools/javac/options/XjcovUnionTypeTest.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, 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 8059453 + * @summary -Xjcov causes crash with union types + * @compile -Xjcov XjcovUnionTypeTest.java + */ + +public class XjcovUnionTypeTest { + public static void main(String[] args) { + try { + return; + } catch (IllegalStateException | IllegalArgumentException e) { + } + } +} From 9d855e2856bd2cb01d59a79f13855ab8cbb1be9d Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Wed, 8 Oct 2014 17:34:27 +0400 Subject: [PATCH 02/67] 8029253: [macosx] Performance problems with Retina display on Mac OS X Reviewed-by: bae, prr --- .../sun/java2d/opengl/OGLBlitLoops.java | 73 +++++++-- .../IncorrectUnmanagedImageSourceOffset.java | 150 ++++++++++++++++++ .../UnmanagedDrawImagePerformance.java | 125 +++++++++++++++ 3 files changed, 333 insertions(+), 15 deletions(-) create mode 100644 jdk/test/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java create mode 100644 jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java index 54cfaf1f58f..9cf237af877 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java @@ -47,7 +47,7 @@ import sun.java2d.pipe.RenderQueue; import static sun.java2d.pipe.BufferedOpCodes.*; import java.lang.annotation.Native; -class OGLBlitLoops { +final class OGLBlitLoops { static void register() { Blit blitIntArgbPreToSurface = @@ -56,7 +56,9 @@ class OGLBlitLoops { Blit blitIntArgbPreToTexture = new OGLSwToTextureBlit(SurfaceType.IntArgbPre, OGLSurfaceData.PF_INT_ARGB_PRE); - + TransformBlit transformBlitIntArgbPreToSurface = + new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre, + OGLSurfaceData.PF_INT_ARGB_PRE); GraphicsPrimitive[] primitives = { // surface->surface ops new OGLSurfaceToSurfaceBlit(), @@ -100,7 +102,7 @@ class OGLBlitLoops { CompositeType.AnyAlpha, blitIntArgbPreToSurface), - new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLSurface), + new OGLAnyCompositeBlit(), new OGLSwToSurfaceScale(SurfaceType.IntRgb, OGLSurfaceData.PF_INT_RGB), @@ -145,8 +147,9 @@ class OGLBlitLoops { OGLSurfaceData.PF_BYTE_GRAY), new OGLSwToSurfaceTransform(SurfaceType.UshortGray, OGLSurfaceData.PF_USHORT_GRAY), - new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre, - OGLSurfaceData.PF_INT_ARGB_PRE), + transformBlitIntArgbPreToSurface, + + new OGLGeneralTransformedBlit(transformBlitIntArgbPreToSurface), // texture->surface ops new OGLTextureToSurfaceBlit(), @@ -178,9 +181,6 @@ class OGLBlitLoops { new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture, CompositeType.SrcNoEa, blitIntArgbPreToTexture), - - new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLTexture), - }; GraphicsPrimitiveMgr.register(primitives); } @@ -781,11 +781,11 @@ class OGLTextureToSurfaceTransform extends TransformBlit { * This general Blit implementation converts any source surface to an * intermediate IntArgbPre surface, and then uses the more specific * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate - * (premultiplied) surface down to OpenGL. + * (premultiplied) surface down to OpenGL using simple blit. */ class OGLGeneralBlit extends Blit { - private Blit performop; + private final Blit performop; private WeakReference srcTmp; OGLGeneralBlit(SurfaceType dstType, @@ -826,12 +826,56 @@ class OGLGeneralBlit extends Blit { } } +/** + * This general TransformedBlit implementation converts any source surface to an + * intermediate IntArgbPre surface, and then uses the more specific + * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate + * (premultiplied) surface down to OpenGL using simple transformBlit. + */ +final class OGLGeneralTransformedBlit extends TransformBlit { + + private final TransformBlit performop; + private WeakReference srcTmp; + + OGLGeneralTransformedBlit(final TransformBlit performop) { + super(SurfaceType.Any, CompositeType.AnyAlpha, + OGLSurfaceData.OpenGLSurface); + this.performop = performop; + } + + @Override + public synchronized void Transform(SurfaceData src, SurfaceData dst, + Composite comp, Region clip, + AffineTransform at, int hint, int srcx, + int srcy, int dstx, int dsty, int width, + int height){ + Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), + CompositeType.SrcNoEa, + SurfaceType.IntArgbPre); + // use cached intermediate surface, if available + final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null; + // convert source to IntArgbPre + src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc, + BufferedImage.TYPE_INT_ARGB_PRE); + + // transform IntArgbPre intermediate surface to OpenGL surface + performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty, + width, height); + + if (src != cachedSrc) { + // cache the intermediate surface + srcTmp = new WeakReference<>(src); + } + } +} + class OGLAnyCompositeBlit extends Blit { private WeakReference dstTmp; - public OGLAnyCompositeBlit(SurfaceType dstType) { - super(SurfaceType.Any, CompositeType.Any, dstType); + OGLAnyCompositeBlit() { + super(SurfaceType.Any, CompositeType.Any, OGLSurfaceData.OpenGLSurface); } + public synchronized void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, @@ -848,15 +892,14 @@ class OGLAnyCompositeBlit extends Blit { cachedDst = dstTmp.get(); } - // convert source to IntArgbPre + // convert destination to IntArgbPre SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h, cachedDst, BufferedImage.TYPE_INT_ARGB_PRE); Blit performop = Blit.getFromCache(src.getSurfaceType(), CompositeType.Any, dstBuffer.getSurfaceType()); - performop.Blit(src, dstBuffer, comp, clip, - sx, sy, 0, 0, w, h); + performop.Blit(src, dstBuffer, comp, clip, sx, sy, 0, 0, w, h); if (dstBuffer != cachedDst) { // cache the intermediate surface diff --git a/jdk/test/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java b/jdk/test/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java new file mode 100644 index 00000000000..98cbcd44faa --- /dev/null +++ b/jdk/test/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.DataBufferShort; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import static java.awt.Transparency.*; +import static java.awt.image.BufferedImage.*; + +/** + * @test + * @bug 8029253 + * @summary Tests asymmetric source offsets when unmanaged image is drawn to VI. + * Results of the blit to compatibleImage are used for comparison. + * @author Sergey Bylokhov + */ +public final class IncorrectUnmanagedImageSourceOffset { + + private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB, + TYPE_INT_ARGB_PRE, TYPE_INT_BGR, + TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR, + TYPE_4BYTE_ABGR_PRE, + /*TYPE_USHORT_565_RGB, + TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY, + TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY, + TYPE_BYTE_INDEXED}; + private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT}; + + public static void main(final String[] args) throws IOException { + for (final int viType : TRANSPARENCIES) { + for (final int biType : TYPES) { + BufferedImage bi = makeUnmanagedBI(biType); + fill(bi); + test(bi, viType); + } + } + } + + private static void test(BufferedImage bi, int type) + throws IOException { + GraphicsEnvironment ge = GraphicsEnvironment + .getLocalGraphicsEnvironment(); + GraphicsConfiguration gc = ge.getDefaultScreenDevice() + .getDefaultConfiguration(); + VolatileImage vi = gc.createCompatibleVolatileImage(511, 255, type); + BufferedImage gold = gc.createCompatibleImage(511, 255, type); + // draw to compatible Image + Graphics2D big = gold.createGraphics(); + // force scaled blit + big.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null); + big.dispose(); + // draw to volatile image + BufferedImage snapshot; + while (true) { + vi.validate(gc); + if (vi.validate(gc) != VolatileImage.IMAGE_OK) { + try { + Thread.sleep(100); + } catch (final InterruptedException ignored) { + } + continue; + } + Graphics2D vig = vi.createGraphics(); + // force scaled blit + vig.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null); + vig.dispose(); + snapshot = vi.getSnapshot(); + if (vi.contentsLost()) { + try { + Thread.sleep(100); + } catch (final InterruptedException ignored) { + } + continue; + } + break; + } + // validate images + for (int x = 7; x < 127; ++x) { + for (int y = 11; y < 111; ++y) { + if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) { + ImageIO.write(gold, "png", new File("gold.png")); + ImageIO.write(snapshot, "png", new File("bi.png")); + throw new RuntimeException("Test failed."); + } + } + } + } + + private static BufferedImage makeUnmanagedBI(final int type) { + final BufferedImage bi = new BufferedImage(511, 255, type); + final DataBuffer db = bi.getRaster().getDataBuffer(); + if (db instanceof DataBufferInt) { + ((DataBufferInt) db).getData(); + } else if (db instanceof DataBufferShort) { + ((DataBufferShort) db).getData(); + } else if (db instanceof DataBufferByte) { + ((DataBufferByte) db).getData(); + } else { + try { + bi.setAccelerationPriority(0.0f); + } catch (final Throwable ignored) { + } + } + return bi; + } + + private static void fill(final Image image) { + final Graphics2D graphics = (Graphics2D) image.getGraphics(); + graphics.setComposite(AlphaComposite.Src); + for (int i = 0; i < image.getHeight(null); ++i) { + graphics.setColor(new Color(i, 0, 0)); + graphics.fillRect(0, i, image.getWidth(null), 1); + } + graphics.dispose(); + } +} diff --git a/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java b/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java new file mode 100644 index 00000000000..67ea6b5af99 --- /dev/null +++ b/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.awt.AlphaComposite; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Polygon; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.DataBufferShort; +import java.awt.image.VolatileImage; + +import static java.awt.Transparency.*; +import static java.awt.image.BufferedImage.*; + +/* + * @test + * @bug 8029253 + * @summary Unmanaged images should be drawn fast. + * @author Sergey Bylokhov + */ +public final class UnmanagedDrawImagePerformance { + + private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB, + TYPE_INT_ARGB_PRE, TYPE_INT_BGR, + TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR, + TYPE_4BYTE_ABGR_PRE, + TYPE_USHORT_565_RGB, + TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY, + TYPE_USHORT_GRAY, TYPE_BYTE_BINARY, + TYPE_BYTE_INDEXED}; + private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT}; + private static final int SIZE = 1000; + private static final AffineTransform[] TRANSFORMS = { + AffineTransform.getScaleInstance(.5, .5), + AffineTransform.getScaleInstance(1, 1), + AffineTransform.getScaleInstance(2, 2), + AffineTransform.getShearInstance(7, 11)}; + + public static void main(final String[] args) { + for (final AffineTransform atfm : TRANSFORMS) { + for (final int viType : TRANSPARENCIES) { + for (final int biType : TYPES) { + final BufferedImage bi = makeUnmanagedBI(biType); + final VolatileImage vi = makeVI(viType); + final long time = test(bi, vi, atfm) / 1000000000; + if (time > 1) { + throw new RuntimeException(String.format( + "drawImage is slow: %d seconds", time)); + } + } + } + } + } + + private static long test(Image bi, Image vi, AffineTransform atfm) { + final Polygon p = new Polygon(); + p.addPoint(0, 0); + p.addPoint(SIZE, 0); + p.addPoint(0, SIZE); + p.addPoint(SIZE, SIZE); + p.addPoint(0, 0); + Graphics2D g2d = (Graphics2D) vi.getGraphics(); + g2d.clip(p); + g2d.transform(atfm); + g2d.setComposite(AlphaComposite.SrcOver); + final long start = System.nanoTime(); + g2d.drawImage(bi, 0, 0, null); + final long time = System.nanoTime() - start; + g2d.dispose(); + return time; + } + + private static VolatileImage makeVI(final int type) { + final GraphicsEnvironment ge = GraphicsEnvironment + .getLocalGraphicsEnvironment(); + final GraphicsDevice gd = ge.getDefaultScreenDevice(); + final GraphicsConfiguration gc = gd.getDefaultConfiguration(); + return gc.createCompatibleVolatileImage(SIZE, SIZE, type); + } + + private static BufferedImage makeUnmanagedBI(final int type) { + final BufferedImage img = new BufferedImage(SIZE, SIZE, type); + final DataBuffer db = img.getRaster().getDataBuffer(); + if (db instanceof DataBufferInt) { + ((DataBufferInt) db).getData(); + } else if (db instanceof DataBufferShort) { + ((DataBufferShort) db).getData(); + } else if (db instanceof DataBufferByte) { + ((DataBufferByte) db).getData(); + } else { + try { + img.setAccelerationPriority(0.0f); + } catch (final Throwable ignored) { + } + } + return img; + } +} From 08fb482e4122fcd5d14a9a14f5570df86a21960e Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Thu, 9 Oct 2014 20:51:39 +0400 Subject: [PATCH 03/67] 8054543: Setting a border on a JLayer causes an Exceptions Reviewed-by: serb, alexsch --- .../share/classes/javax/swing/JLayer.java | 36 +++++++--- .../swing/JLayer/8054543/bug8054543.java | 71 +++++++++++++++++++ 2 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 jdk/test/javax/swing/JLayer/8054543/bug8054543.java diff --git a/jdk/src/java.desktop/share/classes/javax/swing/JLayer.java b/jdk/src/java.desktop/share/classes/javax/swing/JLayer.java index 8c58c916a4e..a4a2aaa5268 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/JLayer.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/JLayer.java @@ -325,23 +325,37 @@ public final class JLayer } /** - * A non-{@code null} border, or non-zero insets, isn't supported, to prevent the geometry - * of this component from becoming complex enough to inhibit - * subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border, - * add it to a {@code JPanel} that has a border. - *

Note: If {@code border} is non-{@code null}, this - * method will throw an exception as borders are not supported on - * a {@code JLayer}. + * Delegates its functionality to the {@code getView().setBorder(Border)} method, + * if the view component is an instance of {@code javax.swing.JComponent}, + * otherwise this method is a no-op. * - * @param border the {@code Border} to set - * @exception IllegalArgumentException this method is not supported + * @param border the border to be rendered for the {@code view} component + * @see #getView() + * @see javax.swing.JComponent#setBorder(Border) */ public void setBorder(Border border) { - if (border != null) { - throw new IllegalArgumentException("JLayer.setBorder() not supported"); + if (view instanceof JComponent) { + ((JComponent)view).setBorder(border); } } + /** + * Delegates its functionality to the {@code getView().getBorder()} method, + * if the view component is an instance of {@code javax.swing.JComponent}, + * otherwise returns {@code null}. + * + * @return the border object for the {@code view} component + * @see #getView() + * @see #setBorder + * @see javax.swing.JComponent#getBorder() + */ + public Border getBorder() { + if (view instanceof JComponent) { + return ((JComponent) view).getBorder(); + } + return null; + } + /** * This method is not supported by {@code JLayer} * and always throws {@code UnsupportedOperationException} diff --git a/jdk/test/javax/swing/JLayer/8054543/bug8054543.java b/jdk/test/javax/swing/JLayer/8054543/bug8054543.java new file mode 100644 index 00000000000..28211b765f0 --- /dev/null +++ b/jdk/test/javax/swing/JLayer/8054543/bug8054543.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, 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 Setting a border on a JLayer causes an Exceptions + * @author Alexander Potochkin + * @run main bug8054543 + */ + +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; + +public class bug8054543 { + + public bug8054543() { + JLayer layer = new JLayer<>(); + Border border = BorderFactory.createLineBorder(Color.GREEN); + JButton view = new JButton("JButton"); + + layer.setBorder(border); + check(layer.getBorder(), null); + + layer.setBorder(null); + check(layer.getBorder(), null); + + layer.setView(view); + check(layer.getBorder(), view.getBorder()); + + layer.setBorder(border); + check(border, view.getBorder()); + + layer.setBorder(null); + check(layer.getBorder(), view.getBorder()); + } + + private void check(Object o1, Object o2) { + if (o1 != o2) { + throw new RuntimeException("Test failed"); + } + } + + public static void main(String... args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + new bug8054543(); + } + }); + } +} From 9a11bfa8229b2dc059938977850a38d59aacfeb5 Mon Sep 17 00:00:00 2001 From: Vivi An Date: Thu, 9 Oct 2014 14:51:12 -0700 Subject: [PATCH 04/67] 8033699: Incorrect radio button behavior Reviewed-by: azvegint, alexsch --- .../swing/plaf/basic/BasicRadioButtonUI.java | 333 +++++++++++++++++- .../JRadioButton/8033699/bug8033699.java | 255 ++++++++++++++ 2 files changed, 584 insertions(+), 4 deletions(-) create mode 100644 jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java diff --git a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java index ec9e88defe1..89066d20695 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java @@ -33,7 +33,8 @@ import javax.swing.plaf.*; import javax.swing.text.View; import sun.swing.SwingUtilities2; import sun.awt.AppContext; - +import java.util.Enumeration; +import java.util.HashSet; /** * RadioButtonUI implementation for BasicRadioButtonUI @@ -53,6 +54,8 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI private final static String propertyPrefix = "RadioButton" + "."; + private KeyListener keyListener = null; + // ******************************** // Create PLAF // ******************************** @@ -74,6 +77,7 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI return radioButtonUI; } + @Override protected String getPropertyPrefix() { return propertyPrefix; } @@ -81,7 +85,8 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI // ******************************** // Install PLAF // ******************************** - protected void installDefaults(AbstractButton b){ + @Override + protected void installDefaults(AbstractButton b) { super.installDefaults(b); if(!defaults_initialized) { icon = UIManager.getIcon(getPropertyPrefix() + "icon"); @@ -92,7 +97,8 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI // ******************************** // Uninstall PLAF // ******************************** - protected void uninstallDefaults(AbstractButton b){ + @Override + protected void uninstallDefaults(AbstractButton b) { super.uninstallDefaults(b); defaults_initialized = false; } @@ -106,6 +112,65 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI return icon; } + // ******************************** + // Install Listeners + // ******************************** + @Override + protected void installListeners(AbstractButton button) { + super.installListeners(button); + + // Only for JRadioButton + if (!(button instanceof JRadioButton)) + return; + + keyListener = createKeyListener(); + button.addKeyListener(keyListener); + + // Need to get traversal key event + button.setFocusTraversalKeysEnabled(false); + + // Map actions to the arrow keys + button.getActionMap().put("Previous", new SelectPreviousBtn()); + button.getActionMap().put("Next", new SelectNextBtn()); + + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT). + put(KeyStroke.getKeyStroke("UP"), "Previous"); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT). + put(KeyStroke.getKeyStroke("DOWN"), "Next"); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT). + put(KeyStroke.getKeyStroke("LEFT"), "Previous"); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT). + put(KeyStroke.getKeyStroke("RIGHT"), "Next"); + } + + // ******************************** + // UnInstall Listeners + // ******************************** + @Override + protected void uninstallListeners(AbstractButton button) { + super.uninstallListeners(button); + + // Only for JRadioButton + if (!(button instanceof JRadioButton)) + return; + + // Unmap actions from the arrow keys + button.getActionMap().remove("Previous"); + button.getActionMap().remove("Next"); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + .remove(KeyStroke.getKeyStroke("UP")); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + .remove(KeyStroke.getKeyStroke("DOWN")); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + .remove(KeyStroke.getKeyStroke("LEFT")); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + .remove(KeyStroke.getKeyStroke("RIGHT")); + + if (keyListener != null) { + button.removeKeyListener(keyListener); + keyListener = null; + } + } /* These Dimensions/Rectangles are allocated once for all * RadioButtonUI.paint() calls. Re-using rectangles @@ -121,6 +186,7 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI /** * paint the radio button */ + @Override public synchronized void paint(Graphics g, JComponent c) { AbstractButton b = (AbstractButton) c; ButtonModel model = b.getModel(); @@ -217,7 +283,7 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI * @param textRect bounds * @param size the size of radio button */ - protected void paintFocus(Graphics g, Rectangle textRect, Dimension size){ + protected void paintFocus(Graphics g, Rectangle textRect, Dimension size) { } @@ -235,6 +301,7 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI /** * The preferred size of the radio button */ + @Override public Dimension getPreferredSize(JComponent c) { if(c.getComponentCount() > 0) { return null; @@ -280,4 +347,262 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI height += prefInsets.top + prefInsets.bottom; return new Dimension(width, height); } + + /////////////////////////// Private functions //////////////////////// + /** + * Creates the key listener to handle tab navigation in JRadioButton Group. + */ + private KeyListener createKeyListener() { + if (keyListener == null) { + keyListener = new KeyHandler(); + } + return keyListener; + } + + + private boolean isValidRadioButtonObj(Object obj) { + return ((obj instanceof JRadioButton) && + ((JRadioButton) obj).isVisible() && + ((JRadioButton) obj).isEnabled()); + } + + /** + * Select radio button based on "Previous" or "Next" operation + * + * @param event, the event object. + * @param next, indicate if it's next one + */ + private void selectRadioButton(ActionEvent event, boolean next) { + // Get the source of the event. + Object eventSrc = event.getSource(); + + // Check whether the source is JRadioButton, it so, whether it is visible + if (!isValidRadioButtonObj(eventSrc)) + return; + + ButtonGroupInfo btnGroupInfo = new ButtonGroupInfo((JRadioButton)eventSrc); + btnGroupInfo.selectNewButton(next); + } + + /////////////////////////// Inner Classes //////////////////////// + @SuppressWarnings("serial") + private class SelectPreviousBtn extends AbstractAction { + public SelectPreviousBtn() { + super("Previous"); + } + + public void actionPerformed(ActionEvent e) { + BasicRadioButtonUI.this.selectRadioButton(e, false); + } + } + + @SuppressWarnings("serial") + private class SelectNextBtn extends AbstractAction{ + public SelectNextBtn() { + super("Next"); + } + + public void actionPerformed(ActionEvent e) { + BasicRadioButtonUI.this.selectRadioButton(e, true); + } + } + + /** + * ButtonGroupInfo, used to get related info in button group + * for given radio button + */ + private class ButtonGroupInfo { + + JRadioButton activeBtn = null; + + JRadioButton firstBtn = null; + JRadioButton lastBtn = null; + + JRadioButton previousBtn = null; + JRadioButton nextBtn = null; + + HashSet btnsInGroup = null; + + boolean srcFound = false; + public ButtonGroupInfo(JRadioButton btn) { + activeBtn = btn; + btnsInGroup = new HashSet(); + } + + // Check if given object is in the button group + boolean containsInGroup(Object obj){ + return btnsInGroup.contains(obj); + } + + // Check if the next object to gain focus belongs + // to the button group or not + Component getFocusTransferBaseComponent(boolean next){ + Component focusBaseComp = activeBtn; + Window container = SwingUtilities.getWindowAncestor(activeBtn); + if (container != null) { + FocusTraversalPolicy policy = container.getFocusTraversalPolicy(); + Component comp = next ? policy.getComponentAfter(container, activeBtn) + : policy.getComponentBefore(container, activeBtn); + + // If next component in the button group, use last/first button as base focus + // otherwise, use the activeBtn as the base focus + if (containsInGroup(comp)) { + focusBaseComp = next ? lastBtn : firstBtn; + } + } + + return focusBaseComp; + } + + boolean getButtonGroupInfo() { + if (activeBtn == null) + return false; + + btnsInGroup.clear(); + + // Get the button model from the source. + ButtonModel model = activeBtn.getModel(); + if (!(model instanceof DefaultButtonModel)) + return false; + + // If the button model is DefaultButtonModel, and use it, otherwise return. + DefaultButtonModel bm = (DefaultButtonModel) model; + + // get the ButtonGroup of the button from the button model + ButtonGroup group = bm.getGroup(); + if (group == null) + return false; + + // Get all the buttons in the group + Enumeration e = group.getElements(); + if (e == null) + return false; + + while (e.hasMoreElements()) { + AbstractButton curElement = e.nextElement(); + if (!isValidRadioButtonObj(curElement)) + continue; + + btnsInGroup.add((JRadioButton) curElement); + + // If firstBtn is not set yet, curElement is that first button + if (null == firstBtn) + firstBtn = (JRadioButton) curElement; + + if (activeBtn == curElement) + srcFound = true; + else if (!srcFound) { + // The source has not been yet found and the current element + // is the last previousBtn + previousBtn = (JRadioButton) curElement; + } else if (nextBtn == null) { + // The source has been found and the current element + // is the next valid button of the list + nextBtn = (JRadioButton) curElement; + } + + // Set new last "valid" JRadioButton of the list + lastBtn = (JRadioButton) curElement; + } + + return true; + } + + /** + * Find the new radio button that focus needs to be + * moved to in the group, select the button + * + * @param next, indicate if it's arrow up/left or down/right + */ + void selectNewButton(boolean next) { + if (!getButtonGroupInfo()) + return; + + if (srcFound) { + JRadioButton newSelectedBtn = null; + if (next) { + // Select Next button. Cycle to the first button if the source + // button is the last of the group. + newSelectedBtn = (null == nextBtn) ? firstBtn : nextBtn; + } else { + // Select previous button. Cycle to the last button if the source + // button is the first button of the group. + newSelectedBtn = (null == previousBtn) ? lastBtn : previousBtn; + } + if (newSelectedBtn != null && + (newSelectedBtn != activeBtn)) { + newSelectedBtn.requestFocusInWindow(); + newSelectedBtn.setSelected(true); + } + } + } + + /** + * Find the button group the passed in JRadioButton belongs to, and + * move focus to next component of the last button in the group + * or previous component of first button + * + * @param next, indicate if jump to next component or previous + */ + void jumpToNextComponent(boolean next) { + if (!getButtonGroupInfo()){ + // In case the button does not belong to any group, it needs + // to be treated as a component + if (activeBtn != null){ + lastBtn = activeBtn; + firstBtn = activeBtn; + } + else + return; + } + + // Update the component we will use as base to transfer + // focus from + JComponent compTransferFocusFrom = activeBtn; + + // If next component in the parent window is not in + // the button group, current active button will be + // base, otherwise, the base will be first or last + // button in the button group + Component focusBase = getFocusTransferBaseComponent(next); + if (focusBase != null){ + if (next) { + KeyboardFocusManager. + getCurrentKeyboardFocusManager().focusNextComponent(focusBase); + } else { + KeyboardFocusManager. + getCurrentKeyboardFocusManager().focusPreviousComponent(focusBase); + } + } + } + } + + /** + * Radiobutton KeyListener + */ + private class KeyHandler implements KeyListener { + + // This listener checks if the key event is a KeyEvent.VK_TAB + // or shift + KeyEvent.VK_TAB event on a radio button, consume the event + // if so and move the focus to next/previous component + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_TAB) { + // Get the source of the event. + Object eventSrc = e.getSource(); + + // Check whether the source is a visible and enabled JRadioButton + if (isValidRadioButtonObj(eventSrc)) { + e.consume(); + ButtonGroupInfo btnGroupInfo = new ButtonGroupInfo((JRadioButton)eventSrc); + btnGroupInfo.jumpToNextComponent(!e.isShiftDown()); + } + } + } + + public void keyReleased(KeyEvent e) { + } + + public void keyTyped(KeyEvent e) { + } + } } diff --git a/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java b/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java new file mode 100644 index 00000000000..63409dead6d --- /dev/null +++ b/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2014, 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 + * @library ../../regtesthelpers + * @build Util + * @bug 8033699 + * @summary Incorrect radio button behavior when pressing tab key + * @author Vivi An + * @run main bug8033699 + */ + +import javax.swing.*; +import javax.swing.event.*; +import java.awt.event.*; +import java.awt.*; +import sun.awt.SunToolkit; + +public class bug8033699 { + private static Robot robot; + private static SunToolkit toolkit; + + private static JButton btnStart; + private static ButtonGroup btnGrp; + private static JButton btnEnd; + private static JButton btnMiddle; + private static JRadioButton radioBtn1; + private static JRadioButton radioBtn2; + private static JRadioButton radioBtn3; + private static JRadioButton radioBtnSingle; + + public static void main(String args[]) throws Throwable { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + + robot = new Robot(); + Thread.sleep(100); + + robot.setAutoDelay(100); + toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + // tab key test grouped radio button + runTest1(); + + // tab key test non-grouped radio button + runTest2(); + + // shift tab key test grouped and non grouped radio button + runTest3(); + + // left/up key test in grouped radio button + runTest4(); + + // down/right key test in grouped radio button + runTest5(); + + // tab from radio button in group to next component in the middle of button group layout + runTest6(); + + // tab to radio button in group from component in the middle of button group layout + runTest7(); + + // down key circle back to first button in grouped radio button + runTest8(); + } + + private static void createAndShowGUI() { + JFrame mainFrame = new JFrame("Bug 8033699 - 8 Tests for Grouped/Non Group Radio Buttons"); + + btnStart = new JButton("Start"); + btnEnd = new JButton("End"); + btnMiddle = new JButton("Middle"); + + JPanel box = new JPanel(); + box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS)); + box.setBorder(BorderFactory.createTitledBorder("Grouped Radio Buttons")); + radioBtn1 = new JRadioButton("A"); + radioBtn2 = new JRadioButton("B"); + radioBtn3 = new JRadioButton("C"); + + ButtonGroup btnGrp = new ButtonGroup(); + btnGrp.add(radioBtn1); + btnGrp.add(radioBtn2); + btnGrp.add(radioBtn3); + radioBtn1.setSelected(true); + + box.add(radioBtn1); + box.add(radioBtn2); + box.add(btnMiddle); + box.add(radioBtn3); + + radioBtnSingle = new JRadioButton("Not Grouped"); + radioBtnSingle.setSelected(true); + + mainFrame.getContentPane().add(btnStart); + mainFrame.getContentPane().add(box); + mainFrame.getContentPane().add(radioBtnSingle); + mainFrame.getContentPane().add(btnEnd); + + mainFrame.getRootPane().setDefaultButton(btnStart); + btnStart.requestFocus(); + + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + mainFrame.setLayout(new BoxLayout(mainFrame.getContentPane(), BoxLayout.Y_AXIS)); + + mainFrame.setSize(300, 300); + mainFrame.setLocation(200, 200); + mainFrame.setVisible(true); + mainFrame.toFront(); + } + + // Radio button Group as a single component when traversing through tab key + private static void runTest1() throws Exception{ + hitKey(robot, KeyEvent.VK_TAB); + hitKey(robot, KeyEvent.VK_TAB); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtnSingle) { + System.out.println("Radio Button Group Go To Next Component through Tab Key failed"); + throw new RuntimeException("Focus is not on Radio Button Single as Expected"); + } + } + }); + } + + // Non-Grouped Radio button as a single component when traversing through tab key + private static void runTest2() throws Exception{ + hitKey(robot, KeyEvent.VK_TAB); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnEnd) { + System.out.println("Non Grouped Radio Button Go To Next Component through Tab Key failed"); + throw new RuntimeException("Focus is not on Button End as Expected"); + } + } + }); + } + + // Non-Grouped Radio button and Group Radio button as a single component when traversing through shift-tab key + private static void runTest3() throws Exception{ + hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); + hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) { + System.out.println("Radio button Group/Non Grouped Radio Button SHIFT-Tab Key Test failed"); + throw new RuntimeException("Focus is not on Radio Button C as Expected"); + } + } + }); + } + + // Using arrow key to move focus in radio button group + private static void runTest4() throws Exception{ + hitKey(robot, KeyEvent.VK_UP); + hitKey(robot, KeyEvent.VK_LEFT); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) { + System.out.println("Radio button Group UP/LEFT Arrow Key Move Focus Failed"); + throw new RuntimeException("Focus is not on Radio Button A as Expected"); + } + } + }); + } + + private static void runTest5() throws Exception{ + hitKey(robot, KeyEvent.VK_DOWN); + hitKey(robot, KeyEvent.VK_RIGHT); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) { + System.out.println("Radio button Group Left/Up Arrow Key Move Focus Failed"); + throw new RuntimeException("Focus is not on Radio Button C as Expected"); + } + } + }); + } + + private static void runTest6() throws Exception{ + hitKey(robot, KeyEvent.VK_DOWN); + hitKey(robot, KeyEvent.VK_DOWN); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn2) { + System.out.println("Radio button Group Circle Back To First Button Test"); + throw new RuntimeException("Focus is not on Radio Button A as Expected"); + } + } + }); + } + + private static void runTest7() throws Exception{ + hitKey(robot, KeyEvent.VK_TAB); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnMiddle) { + System.out.println("Separate Component added in button group layout"); + throw new RuntimeException("Focus is not on Middle Button as Expected"); + } + } + }); + } + + private static void runTest8() throws Exception{ + hitKey(robot, KeyEvent.VK_TAB); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) { + System.out.println("Separate Component added in button group layout"); + throw new RuntimeException("Focus is not on Radio Button C as Expected"); + } + } + }); + } + + private static void hitKey(Robot robot, int keycode) { + robot.keyPress(keycode); + robot.keyRelease(keycode); + toolkit.realSync(); + } + + private static void hitKey(Robot robot, int mode, int keycode) { + robot.keyPress(mode); + robot.keyPress(keycode); + robot.keyRelease(mode); + robot.keyRelease(keycode); + toolkit.realSync(); + } +} From 22976b941ee0e01a7087eae515c1447b1b50b5f1 Mon Sep 17 00:00:00 2001 From: Alexey Ivanov Date: Fri, 10 Oct 2014 11:26:51 +0400 Subject: [PATCH 05/67] 7170310: ScrollBar doesn't become active when tabs are created more than frame size Reviewed-by: alexp, alexsch --- .../swing/plaf/basic/BasicTabbedPaneUI.java | 2 + .../swing/JTabbedPane/7170310/bug7170310.java | 124 ++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 jdk/test/javax/swing/JTabbedPane/7170310/bug7170310.java diff --git a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java index 7490b8ea458..ab754f428c9 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -3249,6 +3249,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } } tabScroller.tabPanel.setPreferredSize(new Dimension(totalWidth, totalHeight)); + tabScroller.tabPanel.invalidate(); } } @@ -3622,6 +3623,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { setFocusIndex(tabPane.getSelectedIndex(), false); if (scrollableTabLayoutEnabled()) { + ensureCurrentLayout(); int index = tabPane.getSelectedIndex(); if (index < rects.length && index != -1) { tabScroller.tabPanel.scrollRectToVisible( diff --git a/jdk/test/javax/swing/JTabbedPane/7170310/bug7170310.java b/jdk/test/javax/swing/JTabbedPane/7170310/bug7170310.java new file mode 100644 index 00000000000..2ceb8a45ccb --- /dev/null +++ b/jdk/test/javax/swing/JTabbedPane/7170310/bug7170310.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.Toolkit; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.JViewport; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.plaf.metal.MetalLookAndFeel; + +import sun.awt.SunToolkit; + +/** + * @test + * @bug 7170310 + * @author Alexey Ivanov + * @summary Selected tab should be scrolled into view. + * @run main bug7170310 + */ +public class bug7170310 { + private static final int TABS_NUMBER = 3; + + private static volatile JTabbedPane tabbedPane; + private static volatile int count = 1; + + private static volatile JFrame frame; + + private static volatile Exception exception = null; + + public static void main(String[] args) throws Exception { + try { + UIManager.setLookAndFeel(new MetalLookAndFeel()); + SwingUtilities.invokeAndWait(bug7170310::createAndShowUI); + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(); + + for (int i = 0; i < TABS_NUMBER; i++) { + SwingUtilities.invokeAndWait(bug7170310::addTab); + toolkit.realSync(); + } + + SwingUtilities.invokeAndWait(bug7170310::check); + + if (exception != null) { + System.out.println("Test failed: " + exception.getMessage()); + throw exception; + } else { + System.out.printf("Test passed"); + } + } finally { + frame.dispose(); + } + } + + private static void createAndShowUI() { + frame = new JFrame("bug7170310"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(200, 100); + + tabbedPane = new JTabbedPane(); + tabbedPane.addTab("Main Tab", new JPanel()); + + tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); + + frame.getContentPane().add(tabbedPane); + frame.setVisible(true); + } + + private static void addTab() { + tabbedPane.addTab("Added Tab " + count++, new JPanel()); + tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1); + } + + private static void check() { + try { + JViewport vp = null; + for (Component c : tabbedPane.getComponents()) { + if (c instanceof JViewport) { + vp = (JViewport) c; + break; + } + } + + JComponent v = (JComponent) vp.getView(); + Rectangle vr = vp.getViewRect(); + Dimension vs = v.getSize(); + + // The tab view must be scrolled to the end so that the last tab is visible + if (vs.width != (vr.x + vr.width)) { + throw new RuntimeException("tabScroller.tabPanel view is positioned incorrectly: " + + vs.width + " vs " + (vr.x + vr.width)); + } + } catch (Exception e) { + exception = e; + } + } +} From 3497cea76cd1d3010861bdd09584687e1840c287 Mon Sep 17 00:00:00 2001 From: Dmitry Markov Date: Fri, 10 Oct 2014 11:36:26 +0400 Subject: [PATCH 06/67] 8058120: Rendering / caret errors with HTMLDocument Reviewed-by: alexp, alexsch --- .../javax/swing/text/html/HTMLDocument.java | 20 +++- .../html/HTMLDocument/8058120/bug8058120.java | 109 ++++++++++++++++++ 2 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 jdk/test/javax/swing/text/html/HTMLDocument/8058120/bug8058120.java diff --git a/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java b/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java index 1166f569728..a981e87f304 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java @@ -1400,8 +1400,13 @@ public class HTMLDocument extends DefaultStyledDocument { Element parent = elem.getParentElement(); if (parent != null) { + // If we are going to insert the string into the body + // section, it is necessary to set the corrsponding flag. + if (HTML.Tag.BODY.name.equals(parent.getName())) { + insertInBody = true; + } int offset = elem.getEndOffset(); - if (offset > getLength()) { + if (offset > (getLength() + 1)) { offset--; } else if (elem.isLeaf() && getText(offset - 1, 1). @@ -1409,6 +1414,10 @@ public class HTMLDocument extends DefaultStyledDocument { offset--; } insertHTML(parent, offset, htmlText, false); + // Cleanup the flag, if any. + if (insertInBody) { + insertInBody = false; + } } } } @@ -1846,6 +1855,11 @@ public class HTMLDocument extends DefaultStyledDocument { private static char[] NEWLINE; + /** + * Indicates that direct insertion to body section takes place. + */ + private boolean insertInBody = false; + /** * I18N property key. * @@ -2610,7 +2624,9 @@ public class HTMLDocument extends DefaultStyledDocument { // Assume content should be added. foundInsertTag(false); foundInsertTag = true; - inParagraph = impliedP = true; + // If content is added directly to the body, it should + // be wrapped by p-implied. + inParagraph = impliedP = !insertInBody; } if (data.length >= 1) { addContent(data, 0, data.length); diff --git a/jdk/test/javax/swing/text/html/HTMLDocument/8058120/bug8058120.java b/jdk/test/javax/swing/text/html/HTMLDocument/8058120/bug8058120.java new file mode 100644 index 00000000000..2378fd2e334 --- /dev/null +++ b/jdk/test/javax/swing/text/html/HTMLDocument/8058120/bug8058120.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014, 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 8058120 + * @summary Rendering / caret errors with HTMLDocument + * @author Dmitry Markov + * @run main bug8058120 + */ + +import sun.awt.SunToolkit; + +import javax.swing.*; +import javax.swing.text.Element; +import javax.swing.text.html.HTML; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLEditorKit; +import java.awt.*; + +public class bug8058120 { + private static SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + private static HTMLDocument document = null; + private static final String text = "

ab

"; + private static final String textToInsert = "c"; + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + createAndShowGUI(); + } + }); + + toolkit.realSync(); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + try { + document.insertAfterEnd(document.getElement("ab"), textToInsert); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + }); + + toolkit.realSync(); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + Element parent = document.getElement("ab").getParentElement(); + int count = parent.getElementCount(); + if (count != 2) { + throw new RuntimeException("Test Failed! Unexpected Element count = "+count); + } + Element insertedElement = parent.getElement(count - 1); + if (!HTML.Tag.IMPLIED.toString().equals(insertedElement.getName())) { + throw new RuntimeException("Test Failed! Inserted text is not wrapped by " + HTML.Tag.IMPLIED + " tag"); + } + } + }); + } + + private static void createAndShowGUI() { + try { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + JFrame frame = new JFrame("bug8058120"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JEditorPane editorPane = new JEditorPane(); + editorPane.setContentType("text/html"); + editorPane.setEditorKit(new HTMLEditorKit()); + + document = (HTMLDocument) editorPane.getDocument(); + + editorPane.setText(text); + + frame.add(editorPane); + frame.setSize(200, 200); + frame.setVisible(true); + } +} + + From d30a6e88b8adf6c02c888a32aee92cd72506af4f Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Fri, 10 Oct 2014 16:07:18 +0400 Subject: [PATCH 07/67] 8059943: [macosx] Aqua LaF should use BI.TYPE_INT_ARGB_PRE for a better performance Reviewed-by: alexsch, azvegint --- .../java.desktop/macosx/classes/com/apple/laf/AquaIcon.java | 2 +- .../macosx/classes/com/apple/laf/AquaImageFactory.java | 2 +- .../macosx/classes/com/apple/laf/AquaNativeResources.java | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaIcon.java b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaIcon.java index 4af5599b600..3a24c35e256 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaIcon.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaIcon.java @@ -62,7 +62,7 @@ public class AquaIcon { if (w <= 0 || h <= 0) return null; // This could be any kind of icon, so we need to make a buffer for it, draw it and then pass the new image off to appkit. - final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE); final Graphics g = image.getGraphics(); i.paintIcon(null, g, 0, 0); g.dispose(); diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java index 4838ba48879..041bec057ae 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java @@ -129,7 +129,7 @@ public class AquaImageFactory { }; final BufferedImage image = new BufferedImage(scaledAlertIconSize, - scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB); + scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB_PRE); final Graphics g = image.getGraphics(); g.drawImage(background, 0, 0, scaledAlertIconSize, scaledAlertIconSize, null); diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java index b43f8965cf2..48c69422f26 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java @@ -67,11 +67,12 @@ public class AquaNativeResources { } static BufferedImage getRadioButtonSizerImage() { - final BufferedImage img = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB); + final BufferedImage img = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB_PRE); Graphics g = img.getGraphics(); g.setColor(Color.pink); g.fillRect(0, 0, 20, 20); + g.dispose(); return img; } From 24155c8965615a766046a6da85a15423a1771640 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Fri, 10 Oct 2014 09:03:28 -0700 Subject: [PATCH 08/67] 8055705: Rename UnixPrintServiceLookup and Win32PrintServiceLookup as a platform neutral class name Reviewed-by: jgodinez, bae --- .../services/javax.print.PrintServiceLookup | 2 + .../javax.print.StreamPrintServiceFactory | 0 .../services/javax.print.PrintServiceLookup | 2 - .../unix/classes/sun/print/CUPSPrinter.java | 4 +- .../classes/sun/print/IPPPrintService.java | 4 +- ...p.java => PrintServiceLookupProvider.java} | 6 +- .../unix/classes/sun/print/UnixPrintJob.java | 4 +- .../classes/sun/print/UnixPrintService.java | 58 +++++++++---------- .../services/javax.print.PrintServiceLookup | 2 - .../javax.print.StreamPrintServiceFactory | 2 - .../classes/sun/awt/windows/WPrinterJob.java | 6 +- ...p.java => PrintServiceLookupProvider.java} | 8 +-- .../native/libawt/windows/WPrinterJob.cpp | 10 ++-- 13 files changed, 52 insertions(+), 56 deletions(-) create mode 100644 jdk/src/java.desktop/share/classes/META-INF/services/javax.print.PrintServiceLookup rename jdk/src/java.desktop/{unix => share}/classes/META-INF/services/javax.print.StreamPrintServiceFactory (100%) delete mode 100644 jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.PrintServiceLookup rename jdk/src/java.desktop/unix/classes/sun/print/{UnixPrintServiceLookup.java => PrintServiceLookupProvider.java} (99%) delete mode 100644 jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.PrintServiceLookup delete mode 100644 jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.StreamPrintServiceFactory rename jdk/src/java.desktop/windows/classes/sun/print/{Win32PrintServiceLookup.java => PrintServiceLookupProvider.java} (98%) diff --git a/jdk/src/java.desktop/share/classes/META-INF/services/javax.print.PrintServiceLookup b/jdk/src/java.desktop/share/classes/META-INF/services/javax.print.PrintServiceLookup new file mode 100644 index 00000000000..bbeb657da4e --- /dev/null +++ b/jdk/src/java.desktop/share/classes/META-INF/services/javax.print.PrintServiceLookup @@ -0,0 +1,2 @@ +# Provider for Java Print Service +sun.print.PrintServiceLookupProvider diff --git a/jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.StreamPrintServiceFactory b/jdk/src/java.desktop/share/classes/META-INF/services/javax.print.StreamPrintServiceFactory similarity index 100% rename from jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.StreamPrintServiceFactory rename to jdk/src/java.desktop/share/classes/META-INF/services/javax.print.StreamPrintServiceFactory diff --git a/jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.PrintServiceLookup b/jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.PrintServiceLookup deleted file mode 100644 index 74beed61735..00000000000 --- a/jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.PrintServiceLookup +++ /dev/null @@ -1,2 +0,0 @@ -# Provider for Java Print Service -sun.print.UnixPrintServiceLookup diff --git a/jdk/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java b/jdk/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java index 6d1b54e32f3..b4a3f9ad3f9 100644 --- a/jdk/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java +++ b/jdk/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java @@ -324,8 +324,8 @@ public class CUPSPrinter { * reported, exec lpstat -d which has all the Apple * special behaviour for this built in. */ - if (UnixPrintServiceLookup.isMac()) { - printerInfo[0] = UnixPrintServiceLookup. + if (PrintServiceLookupProvider.isMac()) { + printerInfo[0] = PrintServiceLookupProvider. getDefaultPrinterNameSysV(); printerInfo[1] = null; return printerInfo.clone(); diff --git a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java index 22cc7bb48bf..3cbdb1ac726 100644 --- a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java +++ b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java @@ -1045,7 +1045,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { setting like collation. Therefore, we temporarily exclude Linux. */ - if (!UnixPrintServiceLookup.isLinux()) { + if (!PrintServiceLookupProvider.isLinux()) { catList.add(SheetCollate.class); } } @@ -1637,7 +1637,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { * Mac is using printer-info IPP attribute for its human-readable printer * name and is also the identifier used in NSPrintInfo:setPrinter. */ - if (UnixPrintServiceLookup.isMac()) { + if (PrintServiceLookupProvider.isMac()) { PrintServiceAttributeSet psaSet = this.getAttributes(); if (psaSet != null) { PrinterInfo pName = (PrinterInfo)psaSet.get(PrinterInfo.class); diff --git a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintServiceLookup.java b/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java similarity index 99% rename from jdk/src/java.desktop/unix/classes/sun/print/UnixPrintServiceLookup.java rename to jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java index 25b9da12842..96acd53d58a 100644 --- a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintServiceLookup.java +++ b/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java @@ -58,7 +58,7 @@ import java.nio.file.Files; * Remind: This class uses solaris commands. We also need a linux * version */ -public class UnixPrintServiceLookup extends PrintServiceLookup +public class PrintServiceLookupProvider extends PrintServiceLookup implements BackgroundServiceLookup, Runnable { /* Remind: the current implementation is static, as its assumed @@ -70,7 +70,7 @@ public class UnixPrintServiceLookup extends PrintServiceLookup private PrintService defaultPrintService; private PrintService[] printServices; /* includes the default printer */ private Vector lookupListeners = null; - private static String debugPrefix = "UnixPrintServiceLookup>> "; + private static String debugPrefix = "PrintServiceLookupProvider>> "; private static boolean pollServices = true; private static final int DEFAULT_MINREFRESH = 120; // 2 minutes private static int minRefreshTime = DEFAULT_MINREFRESH; @@ -208,7 +208,7 @@ public class UnixPrintServiceLookup extends PrintServiceLookup } - public UnixPrintServiceLookup() { + public PrintServiceLookupProvider() { // start the printer listener thread if (pollServices) { PrinterChangeListener thr = new PrinterChangeListener(); diff --git a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java b/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java index 496dfb7abeb..46a776e3b3d 100644 --- a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java +++ b/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java @@ -122,7 +122,7 @@ public class UnixPrintJob implements CancelablePrintJob { UnixPrintJob(PrintService service) { this.service = service; mDestination = service.getName(); - if (UnixPrintServiceLookup.isMac()) { + if (PrintServiceLookupProvider.isMac()) { mDestination = ((IPPPrintService)service).getDest(); } mDestType = UnixPrintJob.DESTPRINTER; @@ -880,7 +880,7 @@ public class UnixPrintJob implements CancelablePrintJob { pFlags |= NOSHEET; ncomps+=1; } - if (UnixPrintServiceLookup.osname.equals("SunOS")) { + if (PrintServiceLookupProvider.osname.equals("SunOS")) { ncomps+=1; // lp uses 1 more arg than lpr (make a copy) execCmd = new String[ncomps]; execCmd[n++] = "/usr/bin/lp"; diff --git a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintService.java b/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintService.java index ac60fa7ec38..91f0e2350ca 100644 --- a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintService.java +++ b/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintService.java @@ -220,7 +220,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsSysV() { String command = "/usr/bin/lpstat -a " + printer; - String results[]= UnixPrintServiceLookup.execCmd(command); + String results[]= PrintServiceLookupProvider.execCmd(command); if (results != null && results.length > 0) { if (results[0].startsWith(printer + " accepting requests")) { @@ -244,20 +244,20 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsBSD() { - if (UnixPrintServiceLookup.cmdIndex == - UnixPrintServiceLookup.UNINITIALIZED) { + if (PrintServiceLookupProvider.cmdIndex == + PrintServiceLookupProvider.UNINITIALIZED) { - UnixPrintServiceLookup.cmdIndex = - UnixPrintServiceLookup.getBSDCommandIndex(); + PrintServiceLookupProvider.cmdIndex = + PrintServiceLookupProvider.getBSDCommandIndex(); } String command = "/usr/sbin/lpc status " + printer - + lpcStatusCom[UnixPrintServiceLookup.cmdIndex]; - String results[]= UnixPrintServiceLookup.execCmd(command); + + lpcStatusCom[PrintServiceLookupProvider.cmdIndex]; + String results[]= PrintServiceLookupProvider.execCmd(command); if (results != null && results.length > 0) { - if (UnixPrintServiceLookup.cmdIndex == - UnixPrintServiceLookup.BSD_LPD_NG) { + if (PrintServiceLookupProvider.cmdIndex == + PrintServiceLookupProvider.BSD_LPD_NG) { if (results[0].startsWith("enabled enabled")) { return PrinterIsAcceptingJobs.ACCEPTING_JOBS ; } @@ -276,7 +276,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, // Filter the list of possible AIX Printers and remove header lines // and extra lines which have been added for remote printers. - // 'protected' because this method is also used from UnixPrintServiceLookup. + // 'protected' because this method is also used from PrintServiceLookupProvider. protected static String[] filterPrinterNamesAIX(String[] posPrinters) { ArrayList printers = new ArrayList<>(); String [] splitPart; @@ -301,7 +301,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsAIX() { // On AIX there should not be a blank after '-a'. String command = "/usr/bin/lpstat -a" + printer; - String results[]= UnixPrintServiceLookup.execCmd(command); + String results[]= PrintServiceLookupProvider.execCmd(command); // Remove headers and bogus entries added by remote printers. results = filterPrinterNamesAIX(results); @@ -320,11 +320,11 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() { - if (UnixPrintServiceLookup.isSysV()) { + if (PrintServiceLookupProvider.isSysV()) { return getPrinterIsAcceptingJobsSysV(); - } else if (UnixPrintServiceLookup.isBSD()) { + } else if (PrintServiceLookupProvider.isBSD()) { return getPrinterIsAcceptingJobsBSD(); - } else if (UnixPrintServiceLookup.isAIX()) { + } else if (PrintServiceLookupProvider.isAIX()) { return getPrinterIsAcceptingJobsAIX(); } else { return PrinterIsAcceptingJobs.ACCEPTING_JOBS; @@ -351,29 +351,29 @@ public class UnixPrintService implements PrintService, AttributeUpdater, private QueuedJobCount getQueuedJobCountSysV() { String command = "/usr/bin/lpstat -R " + printer; - String results[]= UnixPrintServiceLookup.execCmd(command); + String results[]= PrintServiceLookupProvider.execCmd(command); int qlen = (results == null) ? 0 : results.length; return new QueuedJobCount(qlen); } private QueuedJobCount getQueuedJobCountBSD() { - if (UnixPrintServiceLookup.cmdIndex == - UnixPrintServiceLookup.UNINITIALIZED) { + if (PrintServiceLookupProvider.cmdIndex == + PrintServiceLookupProvider.UNINITIALIZED) { - UnixPrintServiceLookup.cmdIndex = - UnixPrintServiceLookup.getBSDCommandIndex(); + PrintServiceLookupProvider.cmdIndex = + PrintServiceLookupProvider.getBSDCommandIndex(); } int qlen = 0; String command = "/usr/sbin/lpc status " + printer - + lpcQueueCom[UnixPrintServiceLookup.cmdIndex]; - String results[] = UnixPrintServiceLookup.execCmd(command); + + lpcQueueCom[PrintServiceLookupProvider.cmdIndex]; + String results[] = PrintServiceLookupProvider.execCmd(command); if (results != null && results.length > 0) { String queued; - if (UnixPrintServiceLookup.cmdIndex == - UnixPrintServiceLookup.BSD_LPD_NG) { + if (PrintServiceLookupProvider.cmdIndex == + PrintServiceLookupProvider.BSD_LPD_NG) { queued = results[0]; } else { queued = results[3].trim(); @@ -396,7 +396,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, private QueuedJobCount getQueuedJobCountAIX() { // On AIX there should not be a blank after '-a'. String command = "/usr/bin/lpstat -a" + printer; - String results[]= UnixPrintServiceLookup.execCmd(command); + String results[]= PrintServiceLookupProvider.execCmd(command); // Remove headers and bogus entries added by remote printers. results = filterPrinterNamesAIX(results); @@ -413,11 +413,11 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } private QueuedJobCount getQueuedJobCount() { - if (UnixPrintServiceLookup.isSysV()) { + if (PrintServiceLookupProvider.isSysV()) { return getQueuedJobCountSysV(); - } else if (UnixPrintServiceLookup.isBSD()) { + } else if (PrintServiceLookupProvider.isBSD()) { return getQueuedJobCountBSD(); - } else if (UnixPrintServiceLookup.isAIX()) { + } else if (PrintServiceLookupProvider.isAIX()) { return getQueuedJobCountAIX(); } else { return new QueuedJobCount(0); @@ -468,9 +468,9 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } private PrintServiceAttributeSet getDynamicAttributes() { - if (UnixPrintServiceLookup.isSysV()) { + if (PrintServiceLookupProvider.isSysV()) { return getSysVServiceAttributes(); - } else if (UnixPrintServiceLookup.isAIX()) { + } else if (PrintServiceLookupProvider.isAIX()) { return getAIXServiceAttributes(); } else { return getBSDServiceAttributes(); diff --git a/jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.PrintServiceLookup b/jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.PrintServiceLookup deleted file mode 100644 index b3844117e05..00000000000 --- a/jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.PrintServiceLookup +++ /dev/null @@ -1,2 +0,0 @@ -# Provider for Java Print Service -sun.print.Win32PrintServiceLookup diff --git a/jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.StreamPrintServiceFactory b/jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.StreamPrintServiceFactory deleted file mode 100644 index 6ab63408bce..00000000000 --- a/jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.StreamPrintServiceFactory +++ /dev/null @@ -1,2 +0,0 @@ -# Providers for Java 2D/JPS Stream print services. -sun.print.PSStreamPrinterFactory diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java index bade04d05e3..8bf7aa1831c 100644 --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java @@ -93,7 +93,7 @@ import sun.print.SunAlternateMedia; import sun.print.SunPageSelection; import sun.print.Win32MediaTray; import sun.print.Win32PrintService; -import sun.print.Win32PrintServiceLookup; +import sun.print.PrintServiceLookupProvider; import sun.print.ServiceDialog; import sun.print.DialogOwner; @@ -454,7 +454,7 @@ public final class WPrinterJob extends RasterPrinterJob // native printer is different ! // we update the current PrintService try { - setPrintService(Win32PrintServiceLookup. + setPrintService(PrintServiceLookupProvider. getWin32PrintLUS(). getPrintServiceByName(printerName)); } catch (PrinterException e) { @@ -628,7 +628,7 @@ public final class WPrinterJob extends RasterPrinterJob String printerName = getNativePrintService(); if (printerName != null) { - myService = Win32PrintServiceLookup.getWin32PrintLUS(). + myService = PrintServiceLookupProvider.getWin32PrintLUS(). getPrintServiceByName(printerName); // no need to call setNativePrintService as this name is // currently set in native diff --git a/jdk/src/java.desktop/windows/classes/sun/print/Win32PrintServiceLookup.java b/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java similarity index 98% rename from jdk/src/java.desktop/windows/classes/sun/print/Win32PrintServiceLookup.java rename to jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java index 5a386d7f2ef..b3f56c8b55c 100644 --- a/jdk/src/java.desktop/windows/classes/sun/print/Win32PrintServiceLookup.java +++ b/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java @@ -47,7 +47,7 @@ import javax.print.attribute.PrintServiceAttribute; import javax.print.attribute.PrintServiceAttributeSet; import javax.print.attribute.standard.PrinterName; -public class Win32PrintServiceLookup extends PrintServiceLookup { +public class PrintServiceLookupProvider extends PrintServiceLookup { private String defaultPrinter; private PrintService defaultPrintService; @@ -70,10 +70,10 @@ public class Win32PrintServiceLookup extends PrintServiceLookup { * javax.print.PrintServiceLookup.defaultPrintService() so that the * same instance is stored there. */ - private static Win32PrintServiceLookup win32PrintLUS; + private static PrintServiceLookupProvider win32PrintLUS; /* Think carefully before calling this. Preferably don't call it. */ - public static Win32PrintServiceLookup getWin32PrintLUS() { + public static PrintServiceLookupProvider getWin32PrintLUS() { if (win32PrintLUS == null) { /* This call is internally synchronized. * When it returns an instance of this class will have @@ -84,7 +84,7 @@ public class Win32PrintServiceLookup extends PrintServiceLookup { return win32PrintLUS; } - public Win32PrintServiceLookup() { + public PrintServiceLookupProvider() { if (win32PrintLUS == null) { win32PrintLUS = this; diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp index 11a6b4b8734..5a73e1f1c46 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp @@ -68,7 +68,7 @@ static BOOL IsSupportedLevel(HANDLE hPrinter, DWORD dwLevel) { extern "C" { JNIEXPORT jstring JNICALL -Java_sun_print_Win32PrintServiceLookup_getDefaultPrinterName(JNIEnv *env, +Java_sun_print_PrintServiceLookupProvider_getDefaultPrinterName(JNIEnv *env, jobject peer) { TRY; @@ -119,7 +119,7 @@ Java_sun_print_Win32PrintServiceLookup_getDefaultPrinterName(JNIEnv *env, JNIEXPORT jobjectArray JNICALL -Java_sun_print_Win32PrintServiceLookup_getAllPrinterNames(JNIEnv *env, +Java_sun_print_PrintServiceLookupProvider_getAllPrinterNames(JNIEnv *env, jobject peer) { TRY; @@ -176,7 +176,7 @@ Java_sun_print_Win32PrintServiceLookup_getAllPrinterNames(JNIEnv *env, JNIEXPORT jlong JNICALL -Java_sun_print_Win32PrintServiceLookup_notifyFirstPrinterChange(JNIEnv *env, +Java_sun_print_PrintServiceLookupProvider_notifyFirstPrinterChange(JNIEnv *env, jobject peer, jstring printer) { HANDLE hPrinter; @@ -210,7 +210,7 @@ Java_sun_print_Win32PrintServiceLookup_notifyFirstPrinterChange(JNIEnv *env, JNIEXPORT void JNICALL -Java_sun_print_Win32PrintServiceLookup_notifyClosePrinterChange(JNIEnv *env, +Java_sun_print_PrintServiceLookupProvider_notifyClosePrinterChange(JNIEnv *env, jobject peer, jlong chgObject) { FindClosePrinterChangeNotification((HANDLE)chgObject); @@ -218,7 +218,7 @@ Java_sun_print_Win32PrintServiceLookup_notifyClosePrinterChange(JNIEnv *env, JNIEXPORT jint JNICALL -Java_sun_print_Win32PrintServiceLookup_notifyPrinterChange(JNIEnv *env, +Java_sun_print_PrintServiceLookupProvider_notifyPrinterChange(JNIEnv *env, jobject peer, jlong chgObject) { DWORD dwChange; From 9fc5a5101f06e5df27fba18bc3c568972e3a1e67 Mon Sep 17 00:00:00 2001 From: Mikhail Cherkasov Date: Fri, 10 Oct 2014 20:14:42 +0400 Subject: [PATCH 09/67] 8038919: Requesting focus to a modeless dialog doesn't work on Safari Reviewed-by: ant, serb --- .../sun/lwawt/macosx/CPlatformWindow.java | 7 +++++++ .../classes/sun/lwawt/macosx/LWCToolkit.java | 5 +++++ .../macosx/native/libawt_lwawt/awt/LWCToolkit.m | 17 +++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index 0a381941ede..671fee74657 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -676,6 +676,13 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo @Override // PlatformWindow public void toFront() { final long nsWindowPtr = getNSWindowPtr(); + LWCToolkit lwcToolkit = (LWCToolkit) Toolkit.getDefaultToolkit(); + Window w = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); + if( w != null + && ((LWWindowPeer)w.getPeer()).getPeerType() == LWWindowPeer.PeerType.EMBEDDED_FRAME + && !lwcToolkit.isApplicationActive()) { + lwcToolkit.activateApplicationIgnoringOtherApps(); + } updateFocusabilityForAutoRequestFocus(false); nativePushNSWindowToFront(nsWindowPtr); updateFocusabilityForAutoRequestFocus(true); diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index b184ec0759f..9d01af03eaf 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -811,6 +811,11 @@ public final class LWCToolkit extends LWToolkit { */ public static native boolean isEmbedded(); + /* + * Activates application ignoring other apps. + */ + public native void activateApplicationIgnoringOtherApps(); + /************************ * Native methods section ************************/ diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m index 033a7cea113..930c70e0963 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m @@ -606,6 +606,23 @@ JNF_COCOA_EXIT(env); return active; } +/* + * Class: sun_lwawt_macosx_LWCToolkit + * Method: activateApplicationIgnoringOtherApps + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_activateApplicationIgnoringOtherApps +(JNIEnv *env, jclass clazz) +{ + JNF_COCOA_ENTER(env); + [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ + if(![NSApp isActive]){ + [NSApp activateIgnoringOtherApps:YES]; + } + }]; + JNF_COCOA_EXIT(env); +} + /* * Class: sun_awt_SunToolkit From 0b304cd9ea6901b62473bc72544c34882dab32ea Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Mon, 13 Oct 2014 14:36:44 +0400 Subject: [PATCH 10/67] 8059297: Test api/javax_swing/interactive/JInternalFrameTests.html#JInternalFrame [JInternalFrameTest0007] fails with MotifLookAndFeel Reviewed-by: alexsch, serb --- .../share/classes/javax/swing/JInternalFrame.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/javax/swing/JInternalFrame.java b/jdk/src/java.desktop/share/classes/javax/swing/JInternalFrame.java index fec8440e8cc..6951f842c59 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/JInternalFrame.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/JInternalFrame.java @@ -1141,14 +1141,15 @@ public class JInternalFrame extends JComponent implements /** * Sets an image to be displayed in the titlebar of this internal frame (usually * in the top-left corner). + * Some look and feels might not support displaying an icon in the titlebar. + * * This image is not the desktopIcon object, which * is the image displayed in the JDesktop when * this internal frame is iconified. * * Passing null to this function is valid, - * but the look and feel - * can choose the - * appropriate behavior for that situation, such as displaying no icon + * but the look and feel can choose the appropriate behavior + * for that situation, such as displaying no icon * or a default icon for the look and feel. * * @param icon the Icon to display in the title bar From 25c3ce26aa96953caed856822154d9986c568d06 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Mon, 13 Oct 2014 09:09:41 -0700 Subject: [PATCH 11/67] 8059848: Test java/awt/GraphicsDevice/CloneConfigsTest.java causes JVM crash in OEL 7.0 Reviewed-by: bae, serb --- .../unix/native/common/java2d/opengl/GLXGraphicsConfig.c | 4 ++-- jdk/test/java/awt/GraphicsDevice/CloneConfigsTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/java.desktop/unix/native/common/java2d/opengl/GLXGraphicsConfig.c b/jdk/src/java.desktop/unix/native/common/java2d/opengl/GLXGraphicsConfig.c index 776f62e4aab..7f8c6ff486b 100644 --- a/jdk/src/java.desktop/unix/native/common/java2d/opengl/GLXGraphicsConfig.c +++ b/jdk/src/java.desktop/unix/native/common/java2d/opengl/GLXGraphicsConfig.c @@ -398,8 +398,8 @@ GLXGC_FindBestVisual(JNIEnv *env, jint screen) static GLXPbuffer GLXGC_InitScratchPbuffer(GLXFBConfig fbconfig) { - int pbattrlist[] = {GLX_PBUFFER_WIDTH, 1, - GLX_PBUFFER_HEIGHT, 1, + int pbattrlist[] = {GLX_PBUFFER_WIDTH, 4, + GLX_PBUFFER_HEIGHT, 4, GLX_PRESERVED_CONTENTS, GL_FALSE, 0}; diff --git a/jdk/test/java/awt/GraphicsDevice/CloneConfigsTest.java b/jdk/test/java/awt/GraphicsDevice/CloneConfigsTest.java index 9854a9e2ae4..bc80813b47c 100644 --- a/jdk/test/java/awt/GraphicsDevice/CloneConfigsTest.java +++ b/jdk/test/java/awt/GraphicsDevice/CloneConfigsTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6822057 7124400 + * @bug 6822057 7124400 8059848 * * @summary Test verifies that list of supported graphics configurations * can not be changed via modification of elements of an array From 18c6eadd5f7e8d61255630ef74f5162a713548fa Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Tue, 14 Oct 2014 18:58:06 +0400 Subject: [PATCH 12/67] 7148531: [macosx] In test, the window does not have time to resize before make a screenshot Reviewed-by: alexsch, azvegint --- .../OnScreenRenderingResizeTest.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/jdk/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java b/jdk/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java index 7c323d6912d..be6c97f4fb1 100644 --- a/jdk/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java +++ b/jdk/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, 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 @@ -89,8 +89,13 @@ public class OnScreenRenderingResizeTest { public void update(Graphics g) {} }; frame.setBackground(bgColor); + frame.setUndecorated(true); frame.pack(); - frame.setSize(FRAME_W, FRAME_H); + + GraphicsConfiguration gc = frame.getGraphicsConfiguration(); + Rectangle gcBounds = gc.getBounds(); + frame.setBounds(gcBounds.width / 4, gcBounds.height / 4, FRAME_W, FRAME_H); + frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { done = true; @@ -108,9 +113,8 @@ public class OnScreenRenderingResizeTest { ex.printStackTrace(); } - GraphicsConfiguration gc = frame.getGraphicsConfiguration(); - int maxW = gc.getBounds().width /2; - int maxH = gc.getBounds().height/2; + int maxW = gcBounds.width /2; + int maxH = gcBounds.height/2; int minW = frame.getWidth(); int minH = frame.getHeight(); int incW = 10, incH = 10, cnt = 0; @@ -155,6 +159,7 @@ public class OnScreenRenderingResizeTest { Insets in = frame.getInsets(); frame.getGraphics().drawImage(output, in.left, in.top, null); if (cnt == 90 && robot != null) { + robot.waitForIdle(); // area where we blitted to should be either white or green Point p = frame.getLocationOnScreen(); p.translate(in.left+10, in.top+10); @@ -172,7 +177,7 @@ public class OnScreenRenderingResizeTest { frame.getWidth()-in.left-in.right, frame.getHeight()-in.top-in.bottom-5-IMAGE_H)); int accepted2[] = { Color.white.getRGB() }; - checkBI(bi, accepted1); + checkBI(bi, accepted2); } Thread.yield(); From 7d50d71fe5ddfd464699b1012c3b2442ddbf0bb1 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Tue, 14 Oct 2014 09:34:45 -0700 Subject: [PATCH 13/67] 8058969: Test closed/sun/java2d/cmm/StubCMMShellTest.sh fails Reviewed-by: bae, serb --- .../classes/java/awt/color/ICC_Profile.java | 9 +++- .../java/awt/color/LoadProfileWithSM.java | 43 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/color/LoadProfileWithSM.java diff --git a/jdk/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java b/jdk/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java index 7e8626f8d0d..90f87280a7f 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java +++ b/jdk/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java @@ -48,6 +48,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; @@ -1857,7 +1858,13 @@ public class ICC_Profile implements Serializable { * returns null. */ private static InputStream getStandardProfileInputStream(String fileName) { - return PCMM.class.getResourceAsStream("profiles/" + fileName); + return AccessController.doPrivileged( + new PrivilegedAction() { + public InputStream run () { + return + PCMM.class.getResourceAsStream("profiles/" + fileName); + } + }, null, new FilePermission("<>", "read")); } /** diff --git a/jdk/test/java/awt/color/LoadProfileWithSM.java b/jdk/test/java/awt/color/LoadProfileWithSM.java new file mode 100644 index 00000000000..3af7a6d449d --- /dev/null +++ b/jdk/test/java/awt/color/LoadProfileWithSM.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.awt.color.*; + +/* + * @test + * @bug 8058969 + * @summary test standard profiles loads with SecurityManager installed. + * @run main/othervm LoadProfileWithSM + */ + +public class LoadProfileWithSM { + + public static void main(String[] args) { + System.setSecurityManager(new SecurityManager()); + ICC_Profile profile = + ((ICC_ColorSpace)(ColorSpace.getInstance( + ColorSpace.CS_GRAY))).getProfile(); + /* request profile data in order to force profile loading */ + profile.getData(); + } +} From 98988ffc54a242802e8051982db3355ce9c0f368 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Fri, 17 Oct 2014 15:55:02 -0700 Subject: [PATCH 14/67] 8061267: PrinterJob: Specified Page Ranges not displayed in Windows Native Print Dialog Reviewed-by: bae, jgodinez --- .../libawt/windows/awt_PrintControl.cpp | 11 +++ .../print/PrinterJob/PageRangesDlgTest.java | 84 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 jdk/test/java/awt/print/PrinterJob/PageRangesDlgTest.java diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp index d3d8b5d7b7d..1d87c3d6dc0 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp @@ -771,6 +771,17 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env, jint maxPage = env->CallIntMethod(printCtrl, AwtPrintControl::getMaxPageID); pd.nMaxPage = (maxPage <= (jint)((WORD)-1)) ? (WORD)maxPage : (WORD)-1; + // In the event that the application displays the dialog before + // installing a Printable, but sets a page range, then max page will be 1 + // since the default state of a PrinterJob is an empty "Book" Pageable. + // Windows pops up an error dialog in such a case which isn't very + // forthcoming about the exact problem. + // So if we detect this fix up such a problem here. + if (pd.nMinPage > pd.nFromPage) pd.nMinPage = pd.nFromPage; + if (pd.nMaxPage < pd.nToPage) pd.nMaxPage = pd.nToPage; + if (pd.nFromPage > pd.nMinPage || pd.nToPage < pd.nMaxPage) { + pd.Flags |= PD_PAGENUMS; + } if (env->CallBooleanMethod(printCtrl, AwtPrintControl::getDestID)) { diff --git a/jdk/test/java/awt/print/PrinterJob/PageRangesDlgTest.java b/jdk/test/java/awt/print/PrinterJob/PageRangesDlgTest.java new file mode 100644 index 00000000000..f1f1fdea93e --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PageRangesDlgTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014, 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 8061267 + * @summary The specified page range should be displayed in the dialog + * @run main/manual=yesno PageRangesDlgTest + */ + +import javax.print.*; +import javax.print.attribute.*; +import javax.print.attribute.standard.*; +import java.awt.*; +import java.awt.print.*; + +public class PageRangesDlgTest implements Printable { + + static String[] instr = { + "This test is to check that the print dialog displays the specified", + "page ranges. You must have a printer installed for this test.", + "It is valid only on dialogs which support page ranges", + "In each dialog, check that a page range of 2 to 3 is requested", + "Optionally press Print instead of Cancel, and verify that the", + "correct number/set of pages is printed", + }; + + public static void main(String args[]) throws Exception { + for (int i=0;i Date: Mon, 20 Oct 2014 12:36:16 +0400 Subject: [PATCH 15/67] 8059590: ArrayIndexOutOfBoundsException occurs when Container with overridden getComponents() is deserialized Reviewed-by: serb, ant --- .../share/classes/java/awt/Container.java | 2 +- .../ContainerAIOOBE/ContainerAIOOBE.java | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/Container/ContainerAIOOBE/ContainerAIOOBE.java diff --git a/jdk/src/java.desktop/share/classes/java/awt/Container.java b/jdk/src/java.desktop/share/classes/java/awt/Container.java index 752763e8554..abe6bff20f5 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Container.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Container.java @@ -3696,7 +3696,7 @@ public class Container extends Component { private void writeObject(ObjectOutputStream s) throws IOException { ObjectOutputStream.PutField f = s.putFields(); f.put("ncomponents", component.size()); - f.put("component", getComponentsSync()); + f.put("component", component.toArray(EMPTY_ARRAY)); f.put("layoutMgr", layoutMgr); f.put("dispatcher", dispatcher); f.put("maxSize", maxSize); diff --git a/jdk/test/java/awt/Container/ContainerAIOOBE/ContainerAIOOBE.java b/jdk/test/java/awt/Container/ContainerAIOOBE/ContainerAIOOBE.java new file mode 100644 index 00000000000..677188ac145 --- /dev/null +++ b/jdk/test/java/awt/Container/ContainerAIOOBE/ContainerAIOOBE.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Container; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * @test + * @bug 8059590 + * @summary ArrayIndexOutOfBoundsException occurs when Container with overridden getComponents() is deserialized. + * @author Alexey Ivanov + * @run main ContainerAIOOBE + */ +public class ContainerAIOOBE { + + public static void main(final String[] args) throws Exception { + ZContainer z = new ZContainer(); + z.add(new Button()); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(z); + oos.flush(); + oos.close(); + + byte[] array = baos.toByteArray(); + ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(array)); + + // Reading the object must not throw ArrayIndexOutOfBoundsException + ZContainer zz = (ZContainer) ois.readObject(); + + if (zz.getComponentCount() != 1) { + throw new Exception("deserialized object must have 1 component"); + } + if (!(zz.getComponent(0) instanceof Button)) { + throw new Exception("deserialized object must contain Button component"); + } + if (zz.getComponents().length != 0) { + throw new Exception("deserialized object returns non-empty array"); + } + System.out.println("Test passed"); + } + + static class ZContainer extends Container { + public Component[] getComponents() { + return new Component[0]; + } + } +} From 96909cf5f1896b40a0332801389aa185d5f4b13c Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Mon, 20 Oct 2014 12:48:45 +0400 Subject: [PATCH 16/67] 8059995: Broken link in Package javax.swing.border Reviewed-by: serb, azvegint --- .../share/classes/javax/swing/BorderFactory.java | 2 +- .../share/classes/javax/swing/JComponent.java | 2 +- .../share/classes/javax/swing/border/Border.java | 2 +- .../share/classes/javax/swing/border/package.html | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/javax/swing/BorderFactory.java b/jdk/src/java.desktop/share/classes/javax/swing/BorderFactory.java index 9f2393cb91d..c1e3ad16679 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/BorderFactory.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/BorderFactory.java @@ -35,7 +35,7 @@ import javax.swing.border.*; * possible, this factory will hand out references to shared * Border instances. * For further information and examples see - * How + * How to Use Borders, * a section in The Java Tutorial. * diff --git a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java index 735ca0b72de..c5d230f01b3 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java @@ -126,7 +126,7 @@ import sun.swing.UIClientPropertyKey; * that includes double buffering and support for borders. * For more information see Painting and - * How + * How * to Use Borders, * both of which are sections in The Java Tutorial. * diff --git a/jdk/src/java.desktop/share/classes/javax/swing/border/Border.java b/jdk/src/java.desktop/share/classes/javax/swing/border/Border.java index cbc0f6b6546..2968ff92476 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/border/Border.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/border/Border.java @@ -33,7 +33,7 @@ import java.awt.Component; * Interface describing an object capable of rendering a border * around the edges of a swing component. * For examples of using borders see - * How to Use Borders, + * How to Use Borders, * a section in The Java Tutorial. *

* In the Swing component set, borders supercede Insets as the diff --git a/jdk/src/java.desktop/share/classes/javax/swing/border/package.html b/jdk/src/java.desktop/share/classes/javax/swing/border/package.html index 2341e1e6290..b83b1deaf55 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/border/package.html +++ b/jdk/src/java.desktop/share/classes/javax/swing/border/package.html @@ -40,10 +40,10 @@ provided by the look-and-feel being used. Most of the Swing API is not thread safe. For details, see Threads and Swing, +href="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html" +target="_top">Concurrency in Swing, a section in -The Java Tutorial. @@ -51,7 +51,7 @@ target="_top">The Java Tutorial. For overviews, tutorials, examples, guides, and tool documentation, please see:

From 395720bf70ed165e5a8e3ac81d38da57ad308502 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Mon, 20 Oct 2014 11:22:58 -0700 Subject: [PATCH 17/67] 8061392: PrinterJob NPE when drawing translucent image with null user clip Reviewed-by: bae, jgodinez --- .../sun/awt/windows/WPathGraphics.java | 4 +- .../ImagePrinting/NullClipARGB.java | 74 +++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/print/PrinterJob/ImagePrinting/NullClipARGB.java diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java index 8366598711d..3b90f2fa215 100644 --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java @@ -1400,7 +1400,9 @@ final class WPathGraphics extends PathGraphics { * The saved device transform is needed as the current transform * is not likely to be the same. */ - deviceClip(savedClip.getPathIterator(savedTransform)); + if (savedClip != null) { + deviceClip(savedClip.getPathIterator(savedTransform)); + } /* Scale the bounding rectangle by the scale transform. * Because the scaling transform has only x and y diff --git a/jdk/test/java/awt/print/PrinterJob/ImagePrinting/NullClipARGB.java b/jdk/test/java/awt/print/PrinterJob/ImagePrinting/NullClipARGB.java new file mode 100644 index 00000000000..88d4e43cf98 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/ImagePrinting/NullClipARGB.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, 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 8061392 + * @summary Test no NPE when printing transparency with null clip. + */ + +import java.awt.*; +import java.awt.image.*; +import java.awt.print.*; + +public class NullClipARGB implements Printable { + + public static void main( String[] args ) { + + try { + PrinterJob pj = PrinterJob.getPrinterJob(); + pj.setPrintable(new NullClipARGB()); + pj.print(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + public int print(Graphics g, PageFormat pf, int pageIndex) + throws PrinterException{ + + if (pageIndex != 0) { + return NO_SUCH_PAGE; + } + Graphics2D g2 = (Graphics2D)g; + System.out.println("original clip="+g2.getClip()); + g2.translate(pf.getImageableX(), pf.getImageableY()); + g2.rotate(0.2); + g2.setClip(null); + g2.setColor( Color.BLACK ); + g2.drawString("This text should be visible through the image", 0, 20); + BufferedImage bi = new BufferedImage(100, 100, + BufferedImage.TYPE_INT_ARGB ); + Graphics ig = bi.createGraphics(); + ig.setColor( new Color( 192, 192, 192, 80 ) ); + ig.fillRect( 0, 0, 100, 100 ); + ig.setColor( Color.BLACK ); + ig.drawRect( 0, 0, 99, 99 ); + ig.dispose(); + g2.drawImage(bi, 10, 0, 90, 90, null ); + g2.translate(100, 100); + g2.drawString("This text should also be visible through the image", 0, 20); + g2.drawImage(bi, 10, 0, 90, 90, null ); + return PAGE_EXISTS; + } +} From 066947c32463b6cfd0bdf2fa2499d1e89822cede Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Wed, 22 Oct 2014 12:33:28 +0400 Subject: [PATCH 18/67] 8061456: [OGL] Incorrect clip is used during sw->surface blit in xor mode Reviewed-by: bae, prr --- .../sun/java2d/opengl/OGLBlitLoops.java | 7 +- .../IncorrectClipXorModeSW2Surface.java | 179 ++++++++++++++++++ 2 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 jdk/test/java/awt/image/DrawImage/IncorrectClipXorModeSW2Surface.java diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java index 9cf237af877..88d2c8f9221 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java @@ -869,7 +869,7 @@ final class OGLGeneralTransformedBlit extends TransformBlit { } } -class OGLAnyCompositeBlit extends Blit { +final class OGLAnyCompositeBlit extends Blit { private WeakReference dstTmp; OGLAnyCompositeBlit() { @@ -895,11 +895,12 @@ class OGLAnyCompositeBlit extends Blit { // convert destination to IntArgbPre SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h, cachedDst, BufferedImage.TYPE_INT_ARGB_PRE); + Region bufferClip = + clip == null ? null : clip.getTranslatedRegion(-dx, -dy); Blit performop = Blit.getFromCache(src.getSurfaceType(), CompositeType.Any, dstBuffer.getSurfaceType()); - - performop.Blit(src, dstBuffer, comp, clip, sx, sy, 0, 0, w, h); + performop.Blit(src, dstBuffer, comp, bufferClip, sx, sy, 0, 0, w, h); if (dstBuffer != cachedDst) { // cache the intermediate surface diff --git a/jdk/test/java/awt/image/DrawImage/IncorrectClipXorModeSW2Surface.java b/jdk/test/java/awt/image/DrawImage/IncorrectClipXorModeSW2Surface.java new file mode 100644 index 00000000000..da06f4f0826 --- /dev/null +++ b/jdk/test/java/awt/image/DrawImage/IncorrectClipXorModeSW2Surface.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.DataBufferShort; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import static java.awt.geom.Rectangle2D.Double; + +/** + * @test + * @bug 8061456 + * @summary Tests drawing BI to volatile image using different clips + xor mode. + * Results of the blit BI to compatibleImage is used for comparison. + * @author Sergey Bylokhov + */ +public final class IncorrectClipXorModeSW2Surface { + + private static int[] SIZES = {2, 10, 100}; + private static final Shape[] SHAPES = { + new Rectangle(0, 0, 0, 0), + new Rectangle(0, 0, 1, 1), + new Rectangle(0, 1, 1, 1), + new Rectangle(1, 0, 1, 1), + new Rectangle(1, 1, 1, 1), + + new Double(0, 0, 0.5, 0.5), + new Double(0, 0.5, 0.5, 0.5), + new Double(0.5, 0, 0.5, 0.5), + new Double(0.5, 0.5, 0.5, 0.5), + new Double(0.25, 0.25, 0.5, 0.5), + new Double(0, 0.25, 1, 0.5), + new Double(0.25, 0, 0.5, 1), + + new Double(.10, .10, .20, .20), + new Double(.75, .75, .20, .20), + new Double(.75, .10, .20, .20), + new Double(.10, .75, .20, .20), + }; + + public static void main(final String[] args) throws IOException { + GraphicsEnvironment ge = GraphicsEnvironment + .getLocalGraphicsEnvironment(); + GraphicsConfiguration gc = ge.getDefaultScreenDevice() + .getDefaultConfiguration(); + AffineTransform at; + for (int size : SIZES) { + at = AffineTransform.getScaleInstance(size, size); + for (Shape clip : SHAPES) { + clip = at.createTransformedShape(clip); + for (Shape to : SHAPES) { + to = at.createTransformedShape(to); + // Prepare test images + BufferedImage snapshot; + BufferedImage bi = getBufferedImage(size); + VolatileImage vi = getVolatileImage(gc, size); + while (true) { + vi.validate(gc); + Graphics2D g2d = vi.createGraphics(); + g2d.setColor(Color.GREEN); + g2d.fillRect(0, 0, size, size); + g2d.dispose(); + if (vi.validate(gc) != VolatileImage.IMAGE_OK) { + continue; + } + draw(clip, to, bi, vi); + snapshot = vi.getSnapshot(); + if (vi.contentsLost()) { + continue; + } + break; + } + // Prepare gold images + BufferedImage goldvi = getCompatibleImage(gc, size); + BufferedImage goldbi = getBufferedImage(size); + draw(clip, to, goldbi, goldvi); + validate(snapshot, goldvi); + vi.flush(); + } + } + } + } + + private static void draw(Shape clip, Shape shape, Image from, Image to) { + Graphics2D g2d = (Graphics2D) to.getGraphics(); + g2d.setXORMode(Color.BLACK); + g2d.setClip(clip); + Rectangle toBounds = shape.getBounds(); + g2d.drawImage(from, toBounds.x, toBounds.y, toBounds.width, + toBounds.height, null); + g2d.dispose(); + } + + private static BufferedImage getBufferedImage(int sw) { + final BufferedImage bi = new BufferedImage(sw, sw, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = bi.createGraphics(); + g2d.setColor(Color.RED); + g2d.fillRect(0, 0, sw, sw); + g2d.dispose(); + + final DataBuffer db = bi.getRaster().getDataBuffer(); + if (db instanceof DataBufferInt) { + ((DataBufferInt) db).getData(); + } else if (db instanceof DataBufferShort) { + ((DataBufferShort) db).getData(); + } else if (db instanceof DataBufferByte) { + ((DataBufferByte) db).getData(); + } else { + try { + bi.setAccelerationPriority(0.0f); + } catch (final Throwable ignored) { + } + } + return bi; + } + + private static VolatileImage getVolatileImage(GraphicsConfiguration gc, + int size) { + return gc.createCompatibleVolatileImage(size, size); + } + + private static BufferedImage getCompatibleImage(GraphicsConfiguration gc, + int size) { + BufferedImage image = gc.createCompatibleImage(size, size); + Graphics2D g2d = image.createGraphics(); + g2d.setColor(Color.GREEN); + g2d.fillRect(0, 0, size, size); + g2d.dispose(); + return image; + } + + private static void validate(BufferedImage bi, BufferedImage goldbi) + throws IOException { + for (int x = 0; x < bi.getWidth(); ++x) { + for (int y = 0; y < bi.getHeight(); ++y) { + if (goldbi.getRGB(x, y) != bi.getRGB(x, y)) { + ImageIO.write(bi, "png", new File("actual.png")); + ImageIO.write(goldbi, "png", new File("expected.png")); + throw new RuntimeException("Test failed."); + } + } + } + } +} From 209ffcd9a5eb7c2c21174967de14b1d791ad361d Mon Sep 17 00:00:00 2001 From: Frederic Parain Date: Wed, 22 Oct 2014 02:31:25 -0700 Subject: [PATCH 19/67] 8061618: Removed unused networking functions from os class Reviewed-by: lfoltan, hseigel, dholmes --- hotspot/src/os/aix/vm/os_aix.cpp | 9 --- hotspot/src/os/aix/vm/os_aix.inline.hpp | 78 ------------------- hotspot/src/os/bsd/vm/os_bsd.cpp | 15 ---- hotspot/src/os/bsd/vm/os_bsd.inline.hpp | 77 ------------------ hotspot/src/os/linux/vm/os_linux.cpp | 9 --- hotspot/src/os/linux/vm/os_linux.inline.hpp | 78 ------------------- hotspot/src/os/solaris/vm/os_solaris.cpp | 71 ----------------- .../src/os/solaris/vm/os_solaris.inline.hpp | 28 ------- hotspot/src/os/windows/vm/os_windows.cpp | 64 --------------- hotspot/src/share/vm/runtime/os.hpp | 18 ----- 10 files changed, 447 deletions(-) diff --git a/hotspot/src/os/aix/vm/os_aix.cpp b/hotspot/src/os/aix/vm/os_aix.cpp index bec34838920..fc873a11eed 100644 --- a/hotspot/src/os/aix/vm/os_aix.cpp +++ b/hotspot/src/os/aix/vm/os_aix.cpp @@ -4137,15 +4137,6 @@ int os::available(int fd, jlong *bytes) { return 1; } -int os::socket_available(int fd, jint *pbytes) { - // Linux doc says EINTR not returned, unlike Solaris - int ret = ::ioctl(fd, FIONREAD, pbytes); - - //%% note ioctl can return 0 when successful, JVM_SocketAvailable - // is expected to return 0 on failure and 1 on success to the jdk. - return (ret < 0) ? 0 : 1; -} - // Map a block of memory. char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only, diff --git a/hotspot/src/os/aix/vm/os_aix.inline.hpp b/hotspot/src/os/aix/vm/os_aix.inline.hpp index bb3232bfbc7..5602342b4ff 100644 --- a/hotspot/src/os/aix/vm/os_aix.inline.hpp +++ b/hotspot/src/os/aix/vm/os_aix.inline.hpp @@ -178,92 +178,14 @@ inline int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) { return os::send(fd, buf, nBytes, flags); } -inline int os::timeout(int fd, long timeout) { - julong prevtime,newtime; - struct timeval t; - - gettimeofday(&t, NULL); - prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - - for(;;) { - struct pollfd pfd; - - pfd.fd = fd; - pfd.events = POLLIN | POLLERR; - - int res = ::poll(&pfd, 1, timeout); - - if (res == OS_ERR && errno == EINTR) { - - // On Linux any value < 0 means "forever" - - if(timeout >= 0) { - gettimeofday(&t, NULL); - newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - timeout -= newtime - prevtime; - if(timeout <= 0) - return OS_OK; - prevtime = newtime; - } - } else - return res; - } -} - -inline int os::listen(int fd, int count) { - return ::listen(fd, count); -} - inline int os::connect(int fd, struct sockaddr* him, socklen_t len) { RESTARTABLE_RETURN_INT(::connect(fd, him, len)); } -inline int os::accept(int fd, struct sockaddr* him, socklen_t* len) { - // Linux doc says this can't return EINTR, unlike accept() on Solaris. - // But see attachListener_linux.cpp, LinuxAttachListener::dequeue(). - return (int)::accept(fd, him, len); -} - -inline int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, - sockaddr* from, socklen_t* fromlen) { - RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen)); -} - -inline int os::sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr* to, socklen_t tolen) { - RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen)); -} - -inline int os::socket_shutdown(int fd, int howto) { - return ::shutdown(fd, howto); -} - -inline int os::bind(int fd, struct sockaddr* him, socklen_t len) { - return ::bind(fd, him, len); -} - -inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) { - return ::getsockname(fd, him, len); -} - -inline int os::get_host_name(char* name, int namelen) { - return ::gethostname(name, namelen); -} - inline struct hostent* os::get_host_by_name(char* name) { return ::gethostbyname(name); } -inline int os::get_sock_opt(int fd, int level, int optname, - char* optval, socklen_t* optlen) { - return ::getsockopt(fd, level, optname, optval, optlen); -} - -inline int os::set_sock_opt(int fd, int level, int optname, - const char* optval, socklen_t optlen) { - return ::setsockopt(fd, level, optname, optval, optlen); -} - inline bool os::supports_monotonic_clock() { // mread_real_time() is monotonic on AIX (see os::javaTimeNanos() comments) return true; diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp index 95e026651ac..0d8ba0a2367 100644 --- a/hotspot/src/os/bsd/vm/os_bsd.cpp +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp @@ -3958,21 +3958,6 @@ int os::available(int fd, jlong *bytes) { return 1; } -int os::socket_available(int fd, jint *pbytes) { - if (fd < 0) { - return OS_OK; - } - - int ret; - - RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret); - - //%% note ioctl can return 0 when successful, JVM_SocketAvailable - // is expected to return 0 on failure and 1 on success to the jdk. - - return (ret == OS_ERR) ? 0 : 1; -} - // Map a block of memory. char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only, diff --git a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp index 1eafb9c76e9..3afb5c21a83 100644 --- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp +++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp @@ -181,91 +181,14 @@ inline int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) { return os::send(fd, buf, nBytes, flags); } -inline int os::timeout(int fd, long timeout) { - julong prevtime,newtime; - struct timeval t; - - gettimeofday(&t, NULL); - prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - - for(;;) { - struct pollfd pfd; - - pfd.fd = fd; - pfd.events = POLLIN | POLLERR; - - int res = ::poll(&pfd, 1, timeout); - - if (res == OS_ERR && errno == EINTR) { - - // On Bsd any value < 0 means "forever" - - if(timeout >= 0) { - gettimeofday(&t, NULL); - newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - timeout -= newtime - prevtime; - if(timeout <= 0) - return OS_OK; - prevtime = newtime; - } - } else - return res; - } -} - -inline int os::listen(int fd, int count) { - return ::listen(fd, count); -} - inline int os::connect(int fd, struct sockaddr* him, socklen_t len) { RESTARTABLE_RETURN_INT(::connect(fd, him, len)); } -inline int os::accept(int fd, struct sockaddr* him, socklen_t* len) { - // At least OpenBSD and FreeBSD can return EINTR from accept. - RESTARTABLE_RETURN_INT(::accept(fd, him, len)); -} - -inline int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, - sockaddr* from, socklen_t* fromlen) { - RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen)); -} - -inline int os::sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr *to, socklen_t tolen) { - RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen)); -} - -inline int os::socket_shutdown(int fd, int howto) { - return ::shutdown(fd, howto); -} - -inline int os::bind(int fd, struct sockaddr* him, socklen_t len) { - return ::bind(fd, him, len); -} - -inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) { - return ::getsockname(fd, him, len); -} - -inline int os::get_host_name(char* name, int namelen) { - return ::gethostname(name, namelen); -} - inline struct hostent* os::get_host_by_name(char* name) { return ::gethostbyname(name); } -inline int os::get_sock_opt(int fd, int level, int optname, - char *optval, socklen_t* optlen) { - return ::getsockopt(fd, level, optname, optval, optlen); -} - -inline int os::set_sock_opt(int fd, int level, int optname, - const char* optval, socklen_t optlen) { - return ::setsockopt(fd, level, optname, optval, optlen); -} - inline bool os::supports_monotonic_clock() { #ifdef __APPLE__ return true; diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 3d82d976f37..3e5dc4066d5 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -5211,15 +5211,6 @@ int os::available(int fd, jlong *bytes) { return 1; } -int os::socket_available(int fd, jint *pbytes) { - // Linux doc says EINTR not returned, unlike Solaris - int ret = ::ioctl(fd, FIONREAD, pbytes); - - //%% note ioctl can return 0 when successful, JVM_SocketAvailable - // is expected to return 0 on failure and 1 on success to the jdk. - return (ret < 0) ? 0 : 1; -} - // Map a block of memory. char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only, diff --git a/hotspot/src/os/linux/vm/os_linux.inline.hpp b/hotspot/src/os/linux/vm/os_linux.inline.hpp index d83fb5b7930..ba4b777d520 100644 --- a/hotspot/src/os/linux/vm/os_linux.inline.hpp +++ b/hotspot/src/os/linux/vm/os_linux.inline.hpp @@ -173,92 +173,14 @@ inline int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) { return os::send(fd, buf, nBytes, flags); } -inline int os::timeout(int fd, long timeout) { - julong prevtime,newtime; - struct timeval t; - - gettimeofday(&t, NULL); - prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - - for(;;) { - struct pollfd pfd; - - pfd.fd = fd; - pfd.events = POLLIN | POLLERR; - - int res = ::poll(&pfd, 1, timeout); - - if (res == OS_ERR && errno == EINTR) { - - // On Linux any value < 0 means "forever" - - if(timeout >= 0) { - gettimeofday(&t, NULL); - newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - timeout -= newtime - prevtime; - if(timeout <= 0) - return OS_OK; - prevtime = newtime; - } - } else - return res; - } -} - -inline int os::listen(int fd, int count) { - return ::listen(fd, count); -} - inline int os::connect(int fd, struct sockaddr* him, socklen_t len) { RESTARTABLE_RETURN_INT(::connect(fd, him, len)); } -inline int os::accept(int fd, struct sockaddr* him, socklen_t* len) { - // Linux doc says this can't return EINTR, unlike accept() on Solaris. - // But see attachListener_linux.cpp, LinuxAttachListener::dequeue(). - return (int)::accept(fd, him, len); -} - -inline int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, - sockaddr* from, socklen_t* fromlen) { - RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen)); -} - -inline int os::sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr* to, socklen_t tolen) { - RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen)); -} - -inline int os::socket_shutdown(int fd, int howto) { - return ::shutdown(fd, howto); -} - -inline int os::bind(int fd, struct sockaddr* him, socklen_t len) { - return ::bind(fd, him, len); -} - -inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) { - return ::getsockname(fd, him, len); -} - -inline int os::get_host_name(char* name, int namelen) { - return ::gethostname(name, namelen); -} - inline struct hostent* os::get_host_by_name(char* name) { return ::gethostbyname(name); } -inline int os::get_sock_opt(int fd, int level, int optname, - char* optval, socklen_t* optlen) { - return ::getsockopt(fd, level, optname, optval, optlen); -} - -inline int os::set_sock_opt(int fd, int level, int optname, - const char* optval, socklen_t optlen) { - return ::setsockopt(fd, level, optname, optval, optlen); -} - inline bool os::supports_monotonic_clock() { return Linux::_clock_gettime != NULL; } diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index 109bf44bdc0..dddb4e7e567 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -5912,37 +5912,6 @@ int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) { // a poll() is done with timeout == -1, in which case we repeat with this // "wait forever" value. -int os::timeout(int fd, long timeout) { - int res; - struct timeval t; - julong prevtime, newtime; - static const char* aNull = 0; - struct pollfd pfd; - pfd.fd = fd; - pfd.events = POLLIN; - - assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, - "Assumed _thread_in_native"); - - gettimeofday(&t, &aNull); - prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - - for (;;) { - res = ::poll(&pfd, 1, timeout); - if (res == OS_ERR && errno == EINTR) { - if (timeout != -1) { - gettimeofday(&t, &aNull); - newtime = ((julong)t.tv_sec * 1000) + t.tv_usec /1000; - timeout -= newtime - prevtime; - if (timeout <= 0) { - return OS_OK; - } - prevtime = newtime; - } - } else return res; - } -} - int os::connect(int fd, struct sockaddr *him, socklen_t len) { int _result; _result = ::connect(fd, him, len); @@ -5982,46 +5951,6 @@ int os::connect(int fd, struct sockaddr *him, socklen_t len) { return _result; } -int os::accept(int fd, struct sockaddr* him, socklen_t* len) { - if (fd < 0) { - return OS_ERR; - } - assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, - "Assumed _thread_in_native"); - RESTARTABLE_RETURN_INT((int)::accept(fd, him, len)); -} - -int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, - sockaddr* from, socklen_t* fromlen) { - assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, - "Assumed _thread_in_native"); - RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen)); -} - -int os::sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr* to, socklen_t tolen) { - assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, - "Assumed _thread_in_native"); - RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen)); -} - -int os::socket_available(int fd, jint *pbytes) { - if (fd < 0) { - return OS_OK; - } - int ret; - RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret); - // note: ioctl can return 0 when successful, JVM_SocketAvailable - // is expected to return 0 on failure and 1 on success to the jdk. - return (ret == OS_ERR) ? 0 : 1; -} - -int os::bind(int fd, struct sockaddr* him, socklen_t len) { - assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, - "Assumed _thread_in_native"); - return ::bind(fd, him, len); -} - // Get the default path to the core file // Returns the length of the string int os::get_core_path(char* buffer, size_t bufferSize) { diff --git a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp index 7609abac014..3456414f048 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp +++ b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp @@ -120,38 +120,10 @@ inline int os::socket(int domain, int type, int protocol) { return ::socket(domain, type, protocol); } -inline int os::listen(int fd, int count) { - if (fd < 0) return OS_ERR; - - return ::listen(fd, count); -} - -inline int os::socket_shutdown(int fd, int howto){ - return ::shutdown(fd, howto); -} - -inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len){ - return ::getsockname(fd, him, len); -} - -inline int os::get_host_name(char* name, int namelen){ - return ::gethostname(name, namelen); -} - inline struct hostent* os::get_host_by_name(char* name) { return ::gethostbyname(name); } -inline int os::get_sock_opt(int fd, int level, int optname, - char* optval, socklen_t* optlen) { - return ::getsockopt(fd, level, optname, optval, optlen); -} - -inline int os::set_sock_opt(int fd, int level, int optname, - const char *optval, socklen_t optlen) { - return ::setsockopt(fd, level, optname, optval, optlen); -} - inline bool os::supports_monotonic_clock() { // javaTimeNanos() is monotonic on Solaris, see getTimeNanos() comments return true; diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 2bde459105b..cc3f8f75832 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -5091,39 +5091,14 @@ int os::socket_close(int fd) { return ::closesocket(fd); } -int os::socket_available(int fd, jint *pbytes) { - int ret = ::ioctlsocket(fd, FIONREAD, (u_long*)pbytes); - return (ret < 0) ? 0 : 1; -} - int os::socket(int domain, int type, int protocol) { return ::socket(domain, type, protocol); } -int os::listen(int fd, int count) { - return ::listen(fd, count); -} - int os::connect(int fd, struct sockaddr* him, socklen_t len) { return ::connect(fd, him, len); } -int os::accept(int fd, struct sockaddr* him, socklen_t* len) { - return ::accept(fd, him, len); -} - -int os::sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr* to, socklen_t tolen) { - - return ::sendto(fd, buf, (int)len, flags, to, tolen); -} - -int os::recvfrom(int fd, char *buf, size_t nBytes, uint flags, - sockaddr* from, socklen_t* fromlen) { - - return ::recvfrom(fd, buf, (int)nBytes, flags, from, fromlen); -} - int os::recv(int fd, char* buf, size_t nBytes, uint flags) { return ::recv(fd, buf, (int)nBytes, flags); } @@ -5136,45 +5111,6 @@ int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) { return ::send(fd, buf, (int)nBytes, flags); } -int os::timeout(int fd, long timeout) { - fd_set tbl; - struct timeval t; - - t.tv_sec = timeout / 1000; - t.tv_usec = (timeout % 1000) * 1000; - - tbl.fd_count = 1; - tbl.fd_array[0] = fd; - - return ::select(1, &tbl, 0, 0, &t); -} - -int os::get_host_name(char* name, int namelen) { - return ::gethostname(name, namelen); -} - -int os::socket_shutdown(int fd, int howto) { - return ::shutdown(fd, howto); -} - -int os::bind(int fd, struct sockaddr* him, socklen_t len) { - return ::bind(fd, him, len); -} - -int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) { - return ::getsockname(fd, him, len); -} - -int os::get_sock_opt(int fd, int level, int optname, - char* optval, socklen_t* optlen) { - return ::getsockopt(fd, level, optname, optval, optlen); -} - -int os::set_sock_opt(int fd, int level, int optname, - const char* optval, socklen_t optlen) { - return ::setsockopt(fd, level, optname, optval, optlen); -} - // WINDOWS CONTEXT Flags for THREAD_SAMPLING #if defined(IA32) #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS) diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index d2e78b43a4c..009e2f18c97 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -680,28 +680,10 @@ class os: AllStatic { // SocketInterface (ex HPI SocketInterface ) static int socket(int domain, int type, int protocol); static int socket_close(int fd); - static int socket_shutdown(int fd, int howto); static int recv(int fd, char* buf, size_t nBytes, uint flags); static int send(int fd, char* buf, size_t nBytes, uint flags); static int raw_send(int fd, char* buf, size_t nBytes, uint flags); - static int timeout(int fd, long timeout); - static int listen(int fd, int count); static int connect(int fd, struct sockaddr* him, socklen_t len); - static int bind(int fd, struct sockaddr* him, socklen_t len); - static int accept(int fd, struct sockaddr* him, socklen_t* len); - static int recvfrom(int fd, char* buf, size_t nbytes, uint flags, - struct sockaddr* from, socklen_t* fromlen); - static int get_sock_name(int fd, struct sockaddr* him, socklen_t* len); - static int sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr* to, socklen_t tolen); - static int socket_available(int fd, jint* pbytes); - - static int get_sock_opt(int fd, int level, int optname, - char* optval, socklen_t* optlen); - static int set_sock_opt(int fd, int level, int optname, - const char* optval, socklen_t optlen); - static int get_host_name(char* name, int namelen); - static struct hostent* get_host_by_name(char* name); // Support for signals (see JVM_RaiseSignal, JVM_RegisterSignal) From d1773311724dc6af1a5506b3cd9f79de9afbe89f Mon Sep 17 00:00:00 2001 From: Rohit Agrawal Date: Wed, 22 Oct 2014 13:39:33 +0400 Subject: [PATCH 20/67] 8058197: AWT fails on generic non-reparenting window managers Reviewed-by: azvegint, serb --- jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java index dd98eb01279..265cdb7930e 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java @@ -595,8 +595,13 @@ final class XWM return isNetWMName("Mutter") || isNetWMName("GNOME Shell"); } + static int awtWMNonReparenting = -1; static boolean isNonReparentingWM() { - return (XWM.getWMID() == XWM.COMPIZ_WM || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM); + if (awtWMNonReparenting == -1) { + awtWMNonReparenting = (XToolkit.getEnv("_JAVA_AWT_WM_NONREPARENTING") != null) ? 1 : 0; + } + return (awtWMNonReparenting == 1 || XWM.getWMID() == XWM.COMPIZ_WM + || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM); } /* From ea48bceb5e72162e695c15914dce027ae9a43a1f Mon Sep 17 00:00:00 2001 From: Andreas Eriksson Date: Wed, 22 Oct 2014 13:59:56 +0200 Subject: [PATCH 21/67] 8057043: Type annotations not retained during class redefine / retransform Reviewed-by: coleenp, sspitsyn, jfranck --- .../vm/prims/jvmtiClassFileReconstituter.cpp | 22 + .../share/vm/prims/jvmtiRedefineClasses.cpp | 622 +++++++++++++++++- .../share/vm/prims/jvmtiRedefineClasses.hpp | 17 + .../RedefineTests/RedefineAnnotations.java | 410 ++++++++++++ 4 files changed, 1054 insertions(+), 17 deletions(-) create mode 100644 hotspot/test/runtime/RedefineTests/RedefineAnnotations.java diff --git a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp index c6633bf34a9..53b5850712e 100644 --- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp +++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp @@ -41,6 +41,7 @@ void JvmtiClassFileReconstituter::write_field_infos() { HandleMark hm(thread()); Array* fields_anno = ikh()->fields_annotations(); + Array* fields_type_anno = ikh()->fields_type_annotations(); // Compute the real number of Java fields int java_fields = ikh()->java_fields_count(); @@ -55,6 +56,7 @@ void JvmtiClassFileReconstituter::write_field_infos() { // int offset = ikh()->field_offset( index ); int generic_signature_index = fs.generic_signature_index(); AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index()); + AnnotationArray* type_anno = fields_type_anno == NULL ? NULL : fields_type_anno->at(fs.index()); // JVMSpec| field_info { // JVMSpec| u2 access_flags; @@ -80,6 +82,9 @@ void JvmtiClassFileReconstituter::write_field_infos() { if (anno != NULL) { ++attr_count; // has RuntimeVisibleAnnotations attribute } + if (type_anno != NULL) { + ++attr_count; // has RuntimeVisibleTypeAnnotations attribute + } write_u2(attr_count); @@ -97,6 +102,9 @@ void JvmtiClassFileReconstituter::write_field_infos() { if (anno != NULL) { write_annotations_attribute("RuntimeVisibleAnnotations", anno); } + if (type_anno != NULL) { + write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno); + } } } @@ -537,6 +545,7 @@ void JvmtiClassFileReconstituter::write_method_info(methodHandle method) { AnnotationArray* anno = method->annotations(); AnnotationArray* param_anno = method->parameter_annotations(); AnnotationArray* default_anno = method->annotation_default(); + AnnotationArray* type_anno = method->type_annotations(); // skip generated default interface methods if (method->is_overpass()) { @@ -572,6 +581,9 @@ void JvmtiClassFileReconstituter::write_method_info(methodHandle method) { if (param_anno != NULL) { ++attr_count; // has RuntimeVisibleParameterAnnotations attribute } + if (type_anno != NULL) { + ++attr_count; // has RuntimeVisibleTypeAnnotations attribute + } write_u2(attr_count); if (const_method->code_size() > 0) { @@ -596,6 +608,9 @@ void JvmtiClassFileReconstituter::write_method_info(methodHandle method) { if (param_anno != NULL) { write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno); } + if (type_anno != NULL) { + write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno); + } } // Write the class attributes portion of ClassFile structure @@ -605,6 +620,7 @@ void JvmtiClassFileReconstituter::write_class_attributes() { u2 inner_classes_length = inner_classes_attribute_length(); Symbol* generic_signature = ikh()->generic_signature(); AnnotationArray* anno = ikh()->class_annotations(); + AnnotationArray* type_anno = ikh()->class_type_annotations(); int attr_count = 0; if (generic_signature != NULL) { @@ -622,6 +638,9 @@ void JvmtiClassFileReconstituter::write_class_attributes() { if (anno != NULL) { ++attr_count; // has RuntimeVisibleAnnotations attribute } + if (type_anno != NULL) { + ++attr_count; // has RuntimeVisibleTypeAnnotations attribute + } if (cpool()->operands() != NULL) { ++attr_count; } @@ -643,6 +662,9 @@ void JvmtiClassFileReconstituter::write_class_attributes() { if (anno != NULL) { write_annotations_attribute("RuntimeVisibleAnnotations", anno); } + if (type_anno != NULL) { + write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno); + } if (cpool()->operands() != NULL) { write_bootstrapmethod_attribute(); } diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 796f5580326..9335857ee56 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1569,6 +1569,29 @@ bool VM_RedefineClasses::rewrite_cp_refs(instanceKlassHandle scratch_class, return false; } + // rewrite constant pool references in the class_type_annotations: + if (!rewrite_cp_refs_in_class_type_annotations(scratch_class, THREAD)) { + // propagate failure back to caller + return false; + } + + // rewrite constant pool references in the fields_type_annotations: + if (!rewrite_cp_refs_in_fields_type_annotations(scratch_class, THREAD)) { + // propagate failure back to caller + return false; + } + + // rewrite constant pool references in the methods_type_annotations: + if (!rewrite_cp_refs_in_methods_type_annotations(scratch_class, THREAD)) { + // propagate failure back to caller + return false; + } + + // There can be type annotations in the Code part of a method_info attribute. + // These annotations are not accessible, even by reflection. + // Currently they are not even parsed by the ClassFileParser. + // If runtime access is added they will also need to be rewritten. + // rewrite source file name index: u2 source_file_name_idx = scratch_class->source_file_name_index(); if (source_file_name_idx != 0) { @@ -2239,6 +2262,588 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_methods_default_annotations( } // end rewrite_cp_refs_in_methods_default_annotations() +// Rewrite constant pool references in a class_type_annotations field. +bool VM_RedefineClasses::rewrite_cp_refs_in_class_type_annotations( + instanceKlassHandle scratch_class, TRAPS) { + + AnnotationArray* class_type_annotations = scratch_class->class_type_annotations(); + if (class_type_annotations == NULL || class_type_annotations->length() == 0) { + // no class_type_annotations so nothing to do + return true; + } + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("class_type_annotations length=%d", class_type_annotations->length())); + + int byte_i = 0; // byte index into class_type_annotations + return rewrite_cp_refs_in_type_annotations_typeArray(class_type_annotations, + byte_i, "ClassFile", THREAD); +} // end rewrite_cp_refs_in_class_type_annotations() + + +// Rewrite constant pool references in a fields_type_annotations field. +bool VM_RedefineClasses::rewrite_cp_refs_in_fields_type_annotations( + instanceKlassHandle scratch_class, TRAPS) { + + Array* fields_type_annotations = scratch_class->fields_type_annotations(); + if (fields_type_annotations == NULL || fields_type_annotations->length() == 0) { + // no fields_type_annotations so nothing to do + return true; + } + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("fields_type_annotations length=%d", fields_type_annotations->length())); + + for (int i = 0; i < fields_type_annotations->length(); i++) { + AnnotationArray* field_type_annotations = fields_type_annotations->at(i); + if (field_type_annotations == NULL || field_type_annotations->length() == 0) { + // this field does not have any annotations so skip it + continue; + } + + int byte_i = 0; // byte index into field_type_annotations + if (!rewrite_cp_refs_in_type_annotations_typeArray(field_type_annotations, + byte_i, "field_info", THREAD)) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("bad field_type_annotations at %d", i)); + // propagate failure back to caller + return false; + } + } + + return true; +} // end rewrite_cp_refs_in_fields_type_annotations() + + +// Rewrite constant pool references in a methods_type_annotations field. +bool VM_RedefineClasses::rewrite_cp_refs_in_methods_type_annotations( + instanceKlassHandle scratch_class, TRAPS) { + + for (int i = 0; i < scratch_class->methods()->length(); i++) { + Method* m = scratch_class->methods()->at(i); + AnnotationArray* method_type_annotations = m->constMethod()->type_annotations(); + + if (method_type_annotations == NULL || method_type_annotations->length() == 0) { + // this method does not have any annotations so skip it + continue; + } + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("methods type_annotations length=%d", method_type_annotations->length())); + + int byte_i = 0; // byte index into method_type_annotations + if (!rewrite_cp_refs_in_type_annotations_typeArray(method_type_annotations, + byte_i, "method_info", THREAD)) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("bad method_type_annotations at %d", i)); + // propagate failure back to caller + return false; + } + } + + return true; +} // end rewrite_cp_refs_in_methods_type_annotations() + + +// Rewrite constant pool references in a type_annotations +// field. This "structure" is adapted from the +// RuntimeVisibleTypeAnnotations_attribute described in +// section 4.7.20 of the Java SE 8 Edition of the VM spec: +// +// type_annotations_typeArray { +// u2 num_annotations; +// type_annotation annotations[num_annotations]; +// } +// +bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotations_typeArray( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS) { + + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + // not enough room for num_annotations field + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for num_annotations field")); + return false; + } + + u2 num_annotations = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("num_type_annotations=%d", num_annotations)); + + int calc_num_annotations = 0; + for (; calc_num_annotations < num_annotations; calc_num_annotations++) { + if (!rewrite_cp_refs_in_type_annotation_struct(type_annotations_typeArray, + byte_i_ref, location_mesg, THREAD)) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("bad type_annotation_struct at %d", calc_num_annotations)); + // propagate failure back to caller + return false; + } + } + assert(num_annotations == calc_num_annotations, "sanity check"); + + if (byte_i_ref != type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("read wrong amount of bytes at end of processing " + "type_annotations_typeArray (%d of %d bytes were read)", + byte_i_ref, type_annotations_typeArray->length())); + return false; + } + + return true; +} // end rewrite_cp_refs_in_type_annotations_typeArray() + + +// Rewrite constant pool references in a type_annotation +// field. This "structure" is adapted from the +// RuntimeVisibleTypeAnnotations_attribute described in +// section 4.7.20 of the Java SE 8 Edition of the VM spec: +// +// type_annotation { +// u1 target_type; +// union { +// type_parameter_target; +// supertype_target; +// type_parameter_bound_target; +// empty_target; +// method_formal_parameter_target; +// throws_target; +// localvar_target; +// catch_target; +// offset_target; +// type_argument_target; +// } target_info; +// type_path target_path; +// annotation anno; +// } +// +bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotation_struct( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS) { + + if (!skip_type_annotation_target(type_annotations_typeArray, + byte_i_ref, location_mesg, THREAD)) { + return false; + } + + if (!skip_type_annotation_type_path(type_annotations_typeArray, + byte_i_ref, THREAD)) { + return false; + } + + if (!rewrite_cp_refs_in_annotation_struct(type_annotations_typeArray, + byte_i_ref, THREAD)) { + return false; + } + + return true; +} // end rewrite_cp_refs_in_type_annotation_struct() + + +// Read, verify and skip over the target_type and target_info part +// so that rewriting can continue in the later parts of the struct. +// +// u1 target_type; +// union { +// type_parameter_target; +// supertype_target; +// type_parameter_bound_target; +// empty_target; +// method_formal_parameter_target; +// throws_target; +// localvar_target; +// catch_target; +// offset_target; +// type_argument_target; +// } target_info; +// +bool VM_RedefineClasses::skip_type_annotation_target( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS) { + + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { + // not enough room for a target_type let alone the rest of a type_annotation + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a target_type")); + return false; + } + + u1 target_type = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("target_type=0x%.2x", target_type)); + RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("location=%s", location_mesg)); + + // Skip over target_info + switch (target_type) { + case 0x00: + // kind: type parameter declaration of generic class or interface + // location: ClassFile + case 0x01: + // kind: type parameter declaration of generic method or constructor + // location: method_info + + { + // struct: + // type_parameter_target { + // u1 type_parameter_index; + // } + // + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a type_parameter_target")); + return false; + } + + u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("type_parameter_target: type_parameter_index=%d", + type_parameter_index)); + } break; + + case 0x10: + // kind: type in extends clause of class or interface declaration + // (including the direct superclass of an anonymous class declaration), + // or in implements clause of interface declaration + // location: ClassFile + + { + // struct: + // supertype_target { + // u2 supertype_index; + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a supertype_target")); + return false; + } + + u2 supertype_index = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("supertype_target: supertype_index=%d", supertype_index)); + } break; + + case 0x11: + // kind: type in bound of type parameter declaration of generic class or interface + // location: ClassFile + case 0x12: + // kind: type in bound of type parameter declaration of generic method or constructor + // location: method_info + + { + // struct: + // type_parameter_bound_target { + // u1 type_parameter_index; + // u1 bound_index; + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a type_parameter_bound_target")); + return false; + } + + u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + u1 bound_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("type_parameter_bound_target: type_parameter_index=%d, bound_index=%d", + type_parameter_index, bound_index)); + } break; + + case 0x13: + // kind: type in field declaration + // location: field_info + case 0x14: + // kind: return type of method, or type of newly constructed object + // location: method_info + case 0x15: + // kind: receiver type of method or constructor + // location: method_info + + { + // struct: + // empty_target { + // } + // + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("empty_target")); + } break; + + case 0x16: + // kind: type in formal parameter declaration of method, constructor, or lambda expression + // location: method_info + + { + // struct: + // formal_parameter_target { + // u1 formal_parameter_index; + // } + // + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a formal_parameter_target")); + return false; + } + + u1 formal_parameter_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("formal_parameter_target: formal_parameter_index=%d", + formal_parameter_index)); + } break; + + case 0x17: + // kind: type in throws clause of method or constructor + // location: method_info + + { + // struct: + // throws_target { + // u2 throws_type_index + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a throws_target")); + return false; + } + + u2 throws_type_index = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("throws_target: throws_type_index=%d", throws_type_index)); + } break; + + case 0x40: + // kind: type in local variable declaration + // location: Code + case 0x41: + // kind: type in resource variable declaration + // location: Code + + { + // struct: + // localvar_target { + // u2 table_length; + // struct { + // u2 start_pc; + // u2 length; + // u2 index; + // } table[table_length]; + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + // not enough room for a table_length let alone the rest of a localvar_target + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a localvar_target table_length")); + return false; + } + + u2 table_length = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("localvar_target: table_length=%d", table_length)); + + int table_struct_size = 2 + 2 + 2; // 3 u2 variables per table entry + int table_size = table_length * table_struct_size; + + if ((byte_i_ref + table_size) > type_annotations_typeArray->length()) { + // not enough room for a table + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a table array of length %d", table_length)); + return false; + } + + // Skip over table + byte_i_ref += table_size; + } break; + + case 0x42: + // kind: type in exception parameter declaration + // location: Code + + { + // struct: + // catch_target { + // u2 exception_table_index; + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a catch_target")); + return false; + } + + u2 exception_table_index = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("catch_target: exception_table_index=%d", exception_table_index)); + } break; + + case 0x43: + // kind: type in instanceof expression + // location: Code + case 0x44: + // kind: type in new expression + // location: Code + case 0x45: + // kind: type in method reference expression using ::new + // location: Code + case 0x46: + // kind: type in method reference expression using ::Identifier + // location: Code + + { + // struct: + // offset_target { + // u2 offset; + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a offset_target")); + return false; + } + + u2 offset = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("offset_target: offset=%d", offset)); + } break; + + case 0x47: + // kind: type in cast expression + // location: Code + case 0x48: + // kind: type argument for generic constructor in new expression or + // explicit constructor invocation statement + // location: Code + case 0x49: + // kind: type argument for generic method in method invocation expression + // location: Code + case 0x4A: + // kind: type argument for generic constructor in method reference expression using ::new + // location: Code + case 0x4B: + // kind: type argument for generic method in method reference expression using ::Identifier + // location: Code + + { + // struct: + // type_argument_target { + // u2 offset; + // u1 type_argument_index; + // } + // + if ((byte_i_ref + 3) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a type_argument_target")); + return false; + } + + u2 offset = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("type_argument_target: offset=%d, type_argument_index=%d", + offset, type_argument_index)); + } break; + + default: + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("unknown target_type")); +#ifdef ASSERT + ShouldNotReachHere(); +#endif + return false; + } + + return true; +} // end skip_type_annotation_target() + + +// Read, verify and skip over the type_path part so that rewriting +// can continue in the later parts of the struct. +// +// type_path { +// u1 path_length; +// { +// u1 type_path_kind; +// u1 type_argument_index; +// } path[path_length]; +// } +// +bool VM_RedefineClasses::skip_type_annotation_type_path( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS) { + + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { + // not enough room for a path_length let alone the rest of the type_path + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a type_path")); + return false; + } + + u1 path_length = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("type_path: path_length=%d", path_length)); + + int calc_path_length = 0; + for (; calc_path_length < path_length; calc_path_length++) { + if ((byte_i_ref + 1 + 1) > type_annotations_typeArray->length()) { + // not enough room for a path + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for path entry %d of %d", + calc_path_length, path_length)); + return false; + } + + u1 type_path_kind = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("type_path: path[%d]: type_path_kind=%d, type_argument_index=%d", + calc_path_length, type_path_kind, type_argument_index)); + + if (type_path_kind > 3 || (type_path_kind != 3 && type_argument_index != 0)) { + // not enough room for a path + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("inconsistent type_path values")); + return false; + } + } + assert(path_length == calc_path_length, "sanity check"); + + return true; +} // end skip_type_annotation_type_path() + + // Rewrite constant pool references in the method's stackmap table. // These "structures" are adapted from the StackMapTable_attribute that // is described in section 4.8.4 of the 6.0 version of the VM spec @@ -3223,23 +3828,6 @@ void VM_RedefineClasses::compute_added_deleted_matching_methods() { void VM_RedefineClasses::swap_annotations(instanceKlassHandle the_class, instanceKlassHandle scratch_class) { - // Since there is currently no rewriting of type annotations indexes - // into the CP, we null out type annotations on scratch_class before - // we swap annotations with the_class rather than facing the - // possibility of shipping annotations with broken indexes to - // Java-land. - ClassLoaderData* loader_data = scratch_class->class_loader_data(); - AnnotationArray* new_class_type_annotations = scratch_class->class_type_annotations(); - if (new_class_type_annotations != NULL) { - MetadataFactory::free_array(loader_data, new_class_type_annotations); - scratch_class->annotations()->set_class_type_annotations(NULL); - } - Array* new_field_type_annotations = scratch_class->fields_type_annotations(); - if (new_field_type_annotations != NULL) { - Annotations::free_contents(loader_data, new_field_type_annotations); - scratch_class->annotations()->set_fields_type_annotations(NULL); - } - // Swap annotation fields values Annotations* old_annotations = the_class->annotations(); the_class->set_annotations(scratch_class->annotations()); diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp index 2383aa86e17..8394f5f50a3 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp @@ -452,6 +452,17 @@ class VM_RedefineClasses: public VM_Operation { instanceKlassHandle scratch_class, TRAPS); bool rewrite_cp_refs_in_element_value( AnnotationArray* class_annotations, int &byte_i_ref, TRAPS); + bool rewrite_cp_refs_in_type_annotations_typeArray( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS); + bool rewrite_cp_refs_in_type_annotation_struct( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS); + bool skip_type_annotation_target( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS); + bool skip_type_annotation_type_path( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS); bool rewrite_cp_refs_in_fields_annotations( instanceKlassHandle scratch_class, TRAPS); void rewrite_cp_refs_in_method(methodHandle method, @@ -463,6 +474,12 @@ class VM_RedefineClasses: public VM_Operation { instanceKlassHandle scratch_class, TRAPS); bool rewrite_cp_refs_in_methods_parameter_annotations( instanceKlassHandle scratch_class, TRAPS); + bool rewrite_cp_refs_in_class_type_annotations( + instanceKlassHandle scratch_class, TRAPS); + bool rewrite_cp_refs_in_fields_type_annotations( + instanceKlassHandle scratch_class, TRAPS); + bool rewrite_cp_refs_in_methods_type_annotations( + instanceKlassHandle scratch_class, TRAPS); void rewrite_cp_refs_in_stack_map_table(methodHandle method, TRAPS); void rewrite_cp_refs_in_verification_type_info( address& stackmap_addr_ref, address stackmap_end, u2 frame_i, diff --git a/hotspot/test/runtime/RedefineTests/RedefineAnnotations.java b/hotspot/test/runtime/RedefineTests/RedefineAnnotations.java new file mode 100644 index 00000000000..eb74b68426e --- /dev/null +++ b/hotspot/test/runtime/RedefineTests/RedefineAnnotations.java @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2014, 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 + * @library /testlibrary + * @summary Test that type annotations are retained after a retransform + * @run main RedefineAnnotations buildagent + * @run main/othervm -javaagent:redefineagent.jar RedefineAnnotations + */ + +import static com.oracle.java.testlibrary.Asserts.assertTrue; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.lang.NoSuchFieldException; +import java.lang.NoSuchMethodException; +import java.lang.RuntimeException; +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.lang.instrument.Instrumentation; +import java.lang.instrument.UnmodifiableClassException; +import java.lang.reflect.AnnotatedArrayType; +import java.lang.reflect.AnnotatedParameterizedType; +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.AnnotatedWildcardType; +import java.lang.reflect.Executable; +import java.lang.reflect.TypeVariable; +import java.security.ProtectionDomain; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.internal.org.objectweb.asm.ClassVisitor; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.FieldVisitor; +import static jdk.internal.org.objectweb.asm.Opcodes.ASM5; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE_USE) +@interface TestAnn { + String site(); +} + +public class RedefineAnnotations { + static Instrumentation inst; + public static void premain(String agentArgs, Instrumentation inst) { + RedefineAnnotations.inst = inst; + } + + static class Transformer implements ClassFileTransformer { + + public byte[] asm(ClassLoader loader, String className, + Class classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer) + throws IllegalClassFormatException { + + ClassWriter cw = new ClassWriter(0); + ClassVisitor cv = new ReAddDummyFieldsClassVisitor(ASM5, cw) { }; + ClassReader cr = new ClassReader(classfileBuffer); + cr.accept(cv, 0); + return cw.toByteArray(); + } + + public class ReAddDummyFieldsClassVisitor extends ClassVisitor { + + LinkedList fields = new LinkedList<>(); + + public ReAddDummyFieldsClassVisitor(int api, ClassVisitor cv) { + super(api, cv); + } + + @Override public FieldVisitor visitField(int access, String name, + String desc, String signature, Object value) { + if (name.startsWith("dummy")) { + // Remove dummy field + fields.addLast(new F(access, name, desc, signature, value)); + return null; + } + return cv.visitField(access, name, desc, signature, value); + } + + @Override public void visitEnd() { + F f; + while ((f = fields.pollFirst()) != null) { + // Re-add dummy fields + cv.visitField(f.access, f.name, f.desc, f.signature, f.value); + } + } + + private class F { + private int access; + private String name; + private String desc; + private String signature; + private Object value; + F(int access, String name, String desc, String signature, Object value) { + this.access = access; + this.name = name; + this.desc = desc; + this.signature = signature; + this.value = value; + } + } + } + + @Override public byte[] transform(ClassLoader loader, String className, + Class classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer) + throws IllegalClassFormatException { + + if (className.contains("TypeAnnotatedTestClass")) { + try { + // Here we remove and re-add the dummy fields. This shuffles the constant pool + return asm(loader, className, classBeingRedefined, protectionDomain, classfileBuffer); + } catch (Throwable e) { + // The retransform native code that called this method does not propagate + // exceptions. Instead of getting an uninformative generic error, catch + // problems here and print it, then exit. + e.printStackTrace(); + System.exit(1); + } + } + return null; + } + } + + private static void buildAgent() { + try { + ClassFileInstaller.main("RedefineAnnotations"); + } catch (Exception e) { + throw new RuntimeException("Could not write agent classfile", e); + } + + try { + PrintWriter pw = new PrintWriter("MANIFEST.MF"); + pw.println("Premain-Class: RedefineAnnotations"); + pw.println("Agent-Class: RedefineAnnotations"); + pw.println("Can-Retransform-Classes: true"); + pw.close(); + } catch (FileNotFoundException e) { + throw new RuntimeException("Could not write manifest file for the agent", e); + } + + sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar"); + if (!jarTool.run(new String[] { "-cmf", "MANIFEST.MF", "redefineagent.jar", "RedefineAnnotations.class" })) { + throw new RuntimeException("Could not write the agent jar file"); + } + } + + public static void main(String argv[]) throws NoSuchFieldException, NoSuchMethodException { + if (argv.length == 1 && argv[0].equals("buildagent")) { + buildAgent(); + return; + } + + if (inst == null) { + throw new RuntimeException("Instrumentation object was null"); + } + + RedefineAnnotations test = new RedefineAnnotations(); + test.testTransformAndVerify(); + } + + // Class type annotations + private Annotation classTypeParameterTA; + private Annotation extendsTA; + private Annotation implementsTA; + + // Field type annotations + private Annotation fieldTA; + private Annotation innerTA; + private Annotation[] arrayTA = new Annotation[4]; + private Annotation[] mapTA = new Annotation[5]; + + // Method type annotations + private Annotation returnTA, methodTypeParameterTA, formalParameterTA, throwsTA; + + private void testTransformAndVerify() + throws NoSuchFieldException, NoSuchMethodException { + + Class c = TypeAnnotatedTestClass.class; + Class myClass = c; + + /* + * Verify that the expected annotations are where they should be before transform. + */ + verifyClassTypeAnnotations(c); + verifyFieldTypeAnnotations(c); + verifyMethodTypeAnnotations(c); + + try { + inst.addTransformer(new Transformer(), true); + inst.retransformClasses(myClass); + } catch (UnmodifiableClassException e) { + throw new RuntimeException(e); + } + + /* + * Verify that the expected annotations are where they should be after transform. + * Also verify that before and after are equal. + */ + verifyClassTypeAnnotations(c); + verifyFieldTypeAnnotations(c); + verifyMethodTypeAnnotations(c); + } + + private void verifyClassTypeAnnotations(Class c) { + Annotation anno; + + anno = c.getTypeParameters()[0].getAnnotations()[0]; + verifyTestAnn(classTypeParameterTA, anno, "classTypeParameter"); + classTypeParameterTA = anno; + + anno = c.getAnnotatedSuperclass().getAnnotations()[0]; + verifyTestAnn(extendsTA, anno, "extends"); + extendsTA = anno; + + anno = c.getAnnotatedInterfaces()[0].getAnnotations()[0]; + verifyTestAnn(implementsTA, anno, "implements"); + implementsTA = anno; + } + + private void verifyFieldTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + + verifyBasicFieldTypeAnnotations(c); + verifyInnerFieldTypeAnnotations(c); + verifyArrayFieldTypeAnnotations(c); + verifyMapFieldTypeAnnotations(c); + } + + private void verifyBasicFieldTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + + Annotation anno = c.getDeclaredField("typeAnnotatedBoolean").getAnnotatedType().getAnnotations()[0]; + verifyTestAnn(fieldTA, anno, "field"); + fieldTA = anno; + } + + private void verifyInnerFieldTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + + AnnotatedType at = c.getDeclaredField("typeAnnotatedInner").getAnnotatedType(); + Annotation anno = at.getAnnotations()[0]; + verifyTestAnn(innerTA, anno, "inner"); + innerTA = anno; + } + + private void verifyArrayFieldTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + + Annotation anno; + AnnotatedType at; + + at = c.getDeclaredField("typeAnnotatedArray").getAnnotatedType(); + anno = at.getAnnotations()[0]; + verifyTestAnn(arrayTA[0], anno, "array1"); + arrayTA[0] = anno; + + for (int i = 1; i <= 3; i++) { + at = ((AnnotatedArrayType) at).getAnnotatedGenericComponentType(); + anno = at.getAnnotations()[0]; + verifyTestAnn(arrayTA[i], anno, "array" + (i + 1)); + arrayTA[i] = anno; + } + } + + private void verifyMapFieldTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + + Annotation anno; + AnnotatedType atBase; + AnnotatedType atParameter; + atBase = c.getDeclaredField("typeAnnotatedMap").getAnnotatedType(); + + anno = atBase.getAnnotations()[0]; + verifyTestAnn(mapTA[0], anno, "map1"); + mapTA[0] = anno; + + atParameter = + ((AnnotatedParameterizedType) atBase). + getAnnotatedActualTypeArguments()[0]; + anno = ((AnnotatedWildcardType) atParameter).getAnnotations()[0]; + verifyTestAnn(mapTA[1], anno, "map2"); + mapTA[1] = anno; + + anno = + ((AnnotatedWildcardType) atParameter). + getAnnotatedUpperBounds()[0].getAnnotations()[0]; + verifyTestAnn(mapTA[2], anno, "map3"); + mapTA[2] = anno; + + atParameter = + ((AnnotatedParameterizedType) atBase). + getAnnotatedActualTypeArguments()[1]; + anno = ((AnnotatedParameterizedType) atParameter).getAnnotations()[0]; + verifyTestAnn(mapTA[3], anno, "map4"); + mapTA[3] = anno; + + anno = + ((AnnotatedParameterizedType) atParameter). + getAnnotatedActualTypeArguments()[0].getAnnotations()[0]; + verifyTestAnn(mapTA[4], anno, "map5"); + mapTA[4] = anno; + } + + private void verifyMethodTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + Annotation anno; + Executable typeAnnotatedMethod = + c.getDeclaredMethod("typeAnnotatedMethod", TypeAnnotatedTestClass.class); + + anno = typeAnnotatedMethod.getAnnotatedReturnType().getAnnotations()[0]; + verifyTestAnn(returnTA, anno, "return"); + returnTA = anno; + + anno = typeAnnotatedMethod.getTypeParameters()[0].getAnnotations()[0]; + verifyTestAnn(methodTypeParameterTA, anno, "methodTypeParameter"); + methodTypeParameterTA = anno; + + anno = typeAnnotatedMethod.getAnnotatedParameterTypes()[0].getAnnotations()[0]; + verifyTestAnn(formalParameterTA, anno, "formalParameter"); + formalParameterTA = anno; + + anno = typeAnnotatedMethod.getAnnotatedExceptionTypes()[0].getAnnotations()[0]; + verifyTestAnn(throwsTA, anno, "throws"); + throwsTA = anno; + } + + private static void verifyTestAnn(Annotation verifyAgainst, Annotation anno, String expectedSite) { + verifyTestAnnSite(anno, expectedSite); + + // When called before transform verifyAgainst will be null, when called + // after transform it will be the annotation from before the transform + if (verifyAgainst != null) { + assertTrue(anno.equals(verifyAgainst), + "Annotations do not match before and after." + + " Before: \"" + verifyAgainst + "\", After: \"" + anno + "\""); + } + } + + private static void verifyTestAnnSite(Annotation testAnn, String expectedSite) { + String expectedAnn = "@TestAnn(site=" + expectedSite + ")"; + assertTrue(testAnn.toString().equals(expectedAnn), + "Expected \"" + expectedAnn + "\", got \"" + testAnn + "\""); + } + + public static class TypeAnnotatedTestClass <@TestAnn(site="classTypeParameter") S,T> + extends @TestAnn(site="extends") Thread + implements @TestAnn(site="implements") Runnable { + + public @TestAnn(site="field") boolean typeAnnotatedBoolean; + + public + RedefineAnnotations. + @TestAnn(site="inner") TypeAnnotatedTestClass + typeAnnotatedInner; + + public + @TestAnn(site="array4") boolean + @TestAnn(site="array1") [] + @TestAnn(site="array2") [] + @TestAnn(site="array3") [] + typeAnnotatedArray; + + public @TestAnn(site="map1") Map + <@TestAnn(site="map2") ? extends @TestAnn(site="map3") String, + @TestAnn(site="map4") List<@TestAnn(site="map5") Object>> typeAnnotatedMap; + + public int dummy1; + public int dummy2; + public int dummy3; + + @TestAnn(site="return") <@TestAnn(site="methodTypeParameter") U,V> Class + typeAnnotatedMethod(@TestAnn(site="formalParameter") TypeAnnotatedTestClass arg) + throws @TestAnn(site="throws") ClassNotFoundException { + + @TestAnn(site="local_variable_type") int foo = 0; + throw new ClassNotFoundException(); + } + + public void run() {} + } +} From 0e1283a8117af0f3ffe822f23876aeb0a949e0e0 Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Wed, 22 Oct 2014 15:24:37 -0700 Subject: [PATCH 22/67] 8043275: Fix interface initialization for default methods Initialize interfaces that declare concrete instance methods. Reviewed-by: kamg, coleenp, psandoz --- .../share/vm/classfile/classFileParser.cpp | 20 +- .../vm/classfile/classFileParser.cpp.orig | 5274 +++++++++++++++++ .../share/vm/classfile/classFileParser.hpp | 2 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 65 +- hotspot/src/share/vm/oops/instanceKlass.hpp | 27 +- .../share/vm/utilities/dtrace_disabled.hpp | 2 +- .../InvokespecialInterface.java | 4 +- .../lambda-features/TestInterfaceInit.java | 87 + .../lambda-features/TestInterfaceOrder.java | 88 + 9 files changed, 5525 insertions(+), 44 deletions(-) create mode 100644 hotspot/src/share/vm/classfile/classFileParser.cpp.orig create mode 100644 hotspot/test/runtime/lambda-features/TestInterfaceInit.java create mode 100644 hotspot/test/runtime/lambda-features/TestInterfaceOrder.java diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 0f2f8d590c4..fe9f2443a80 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -2557,7 +2557,7 @@ methodHandle ClassFileParser::parse_method(bool is_interface, Array* ClassFileParser::parse_methods(bool is_interface, AccessFlags* promoted_flags, bool* has_final_method, - bool* has_default_methods, + bool* declares_default_methods, TRAPS) { ClassFileStream* cfs = stream(); cfs->guarantee_more(2, CHECK_NULL); // length @@ -2576,11 +2576,11 @@ Array* ClassFileParser::parse_methods(bool is_interface, if (method->is_final()) { *has_final_method = true; } - if (is_interface && !(*has_default_methods) - && !method->is_abstract() && !method->is_static() - && !method->is_private()) { - // default method - *has_default_methods = true; + // declares_default_methods: declares concrete instance methods, any access flags + // used for interface initialization, and default method inheritance analysis + if (is_interface && !(*declares_default_methods) + && !method->is_abstract() && !method->is_static()) { + *declares_default_methods = true; } _methods->at_put(index, method()); } @@ -3739,6 +3739,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, JvmtiCachedClassFileData *cached_class_file = NULL; Handle class_loader(THREAD, loader_data->class_loader()); bool has_default_methods = false; + bool declares_default_methods = false; ResourceMark rm(THREAD); ClassFileStream* cfs = stream(); @@ -3976,9 +3977,13 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, Array* methods = parse_methods(access_flags.is_interface(), &promoted_flags, &has_final_method, - &has_default_methods, + &declares_default_methods, CHECK_(nullHandle)); + if (declares_default_methods) { + has_default_methods = true; + } + // Additional attributes ClassAnnotationCollector parsed_annotations; parse_classfile_attributes(&parsed_annotations, CHECK_(nullHandle)); @@ -4120,6 +4125,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, this_klass->set_minor_version(minor_version); this_klass->set_major_version(major_version); this_klass->set_has_default_methods(has_default_methods); + this_klass->set_declares_default_methods(declares_default_methods); if (!host_klass.is_null()) { assert (this_klass->is_anonymous(), "should be the same"); diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp.orig b/hotspot/src/share/vm/classfile/classFileParser.cpp.orig new file mode 100644 index 00000000000..0f2f8d590c4 --- /dev/null +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp.orig @@ -0,0 +1,5274 @@ +/* + * Copyright (c) 1997, 2014, 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 "precompiled.hpp" +#include "classfile/classFileParser.hpp" +#include "classfile/classLoader.hpp" +#include "classfile/classLoaderData.hpp" +#include "classfile/classLoaderData.inline.hpp" +#include "classfile/defaultMethods.hpp" +#include "classfile/javaClasses.hpp" +#include "classfile/symbolTable.hpp" +#include "classfile/systemDictionary.hpp" +#if INCLUDE_CDS +#include "classfile/systemDictionaryShared.hpp" +#endif +#include "classfile/verificationType.hpp" +#include "classfile/verifier.hpp" +#include "classfile/vmSymbols.hpp" +#include "memory/allocation.hpp" +#include "memory/gcLocker.hpp" +#include "memory/metadataFactory.hpp" +#include "memory/oopFactory.hpp" +#include "memory/referenceType.hpp" +#include "memory/universe.inline.hpp" +#include "oops/constantPool.hpp" +#include "oops/fieldStreams.hpp" +#include "oops/instanceKlass.hpp" +#include "oops/instanceMirrorKlass.hpp" +#include "oops/klass.inline.hpp" +#include "oops/klassVtable.hpp" +#include "oops/method.hpp" +#include "oops/symbol.hpp" +#include "prims/jvm.h" +#include "prims/jvmtiExport.hpp" +#include "prims/jvmtiThreadState.hpp" +#include "runtime/javaCalls.hpp" +#include "runtime/perfData.hpp" +#include "runtime/reflection.hpp" +#include "runtime/signature.hpp" +#include "runtime/timer.hpp" +#include "services/classLoadingService.hpp" +#include "services/threadService.hpp" +#include "utilities/array.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/ostream.hpp" + +// We generally try to create the oops directly when parsing, rather than +// allocating temporary data structures and copying the bytes twice. A +// temporary area is only needed when parsing utf8 entries in the constant +// pool and when parsing line number tables. + +// We add assert in debug mode when class format is not checked. + +#define JAVA_CLASSFILE_MAGIC 0xCAFEBABE +#define JAVA_MIN_SUPPORTED_VERSION 45 +#define JAVA_MAX_SUPPORTED_VERSION 52 +#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0 + +// Used for two backward compatibility reasons: +// - to check for new additions to the class file format in JDK1.5 +// - to check for bug fixes in the format checker in JDK1.5 +#define JAVA_1_5_VERSION 49 + +// Used for backward compatibility reasons: +// - to check for javac bug fixes that happened after 1.5 +// - also used as the max version when running in jdk6 +#define JAVA_6_VERSION 50 + +// Used for backward compatibility reasons: +// - to check NameAndType_info signatures more aggressively +#define JAVA_7_VERSION 51 + +// Extension method support. +#define JAVA_8_VERSION 52 + +void ClassFileParser::parse_constant_pool_entries(int length, TRAPS) { + // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize + // this function (_current can be allocated in a register, with scalar + // replacement of aggregates). The _current pointer is copied back to + // stream() when this function returns. DON'T call another method within + // this method that uses stream(). + ClassFileStream* cfs0 = stream(); + ClassFileStream cfs1 = *cfs0; + ClassFileStream* cfs = &cfs1; +#ifdef ASSERT + assert(cfs->allocated_on_stack(),"should be local"); + u1* old_current = cfs0->current(); +#endif + Handle class_loader(THREAD, _loader_data->class_loader()); + + // Used for batching symbol allocations. + const char* names[SymbolTable::symbol_alloc_batch_size]; + int lengths[SymbolTable::symbol_alloc_batch_size]; + int indices[SymbolTable::symbol_alloc_batch_size]; + unsigned int hashValues[SymbolTable::symbol_alloc_batch_size]; + int names_count = 0; + + // parsing Index 0 is unused + for (int index = 1; index < length; index++) { + // Each of the following case guarantees one more byte in the stream + // for the following tag or the access_flags following constant pool, + // so we don't need bounds-check for reading tag. + u1 tag = cfs->get_u1_fast(); + switch (tag) { + case JVM_CONSTANT_Class : + { + cfs->guarantee_more(3, CHECK); // name_index, tag/access_flags + u2 name_index = cfs->get_u2_fast(); + _cp->klass_index_at_put(index, name_index); + } + break; + case JVM_CONSTANT_Fieldref : + { + cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags + u2 class_index = cfs->get_u2_fast(); + u2 name_and_type_index = cfs->get_u2_fast(); + _cp->field_at_put(index, class_index, name_and_type_index); + } + break; + case JVM_CONSTANT_Methodref : + { + cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags + u2 class_index = cfs->get_u2_fast(); + u2 name_and_type_index = cfs->get_u2_fast(); + _cp->method_at_put(index, class_index, name_and_type_index); + } + break; + case JVM_CONSTANT_InterfaceMethodref : + { + cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags + u2 class_index = cfs->get_u2_fast(); + u2 name_and_type_index = cfs->get_u2_fast(); + _cp->interface_method_at_put(index, class_index, name_and_type_index); + } + break; + case JVM_CONSTANT_String : + { + cfs->guarantee_more(3, CHECK); // string_index, tag/access_flags + u2 string_index = cfs->get_u2_fast(); + _cp->string_index_at_put(index, string_index); + } + break; + case JVM_CONSTANT_MethodHandle : + case JVM_CONSTANT_MethodType : + if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { + classfile_parse_error( + "Class file version does not support constant tag %u in class file %s", + tag, CHECK); + } + if (tag == JVM_CONSTANT_MethodHandle) { + cfs->guarantee_more(4, CHECK); // ref_kind, method_index, tag/access_flags + u1 ref_kind = cfs->get_u1_fast(); + u2 method_index = cfs->get_u2_fast(); + _cp->method_handle_index_at_put(index, ref_kind, method_index); + } else if (tag == JVM_CONSTANT_MethodType) { + cfs->guarantee_more(3, CHECK); // signature_index, tag/access_flags + u2 signature_index = cfs->get_u2_fast(); + _cp->method_type_index_at_put(index, signature_index); + } else { + ShouldNotReachHere(); + } + break; + case JVM_CONSTANT_InvokeDynamic : + { + if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { + classfile_parse_error( + "Class file version does not support constant tag %u in class file %s", + tag, CHECK); + } + cfs->guarantee_more(5, CHECK); // bsm_index, nt, tag/access_flags + u2 bootstrap_specifier_index = cfs->get_u2_fast(); + u2 name_and_type_index = cfs->get_u2_fast(); + if (_max_bootstrap_specifier_index < (int) bootstrap_specifier_index) + _max_bootstrap_specifier_index = (int) bootstrap_specifier_index; // collect for later + _cp->invoke_dynamic_at_put(index, bootstrap_specifier_index, name_and_type_index); + } + break; + case JVM_CONSTANT_Integer : + { + cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags + u4 bytes = cfs->get_u4_fast(); + _cp->int_at_put(index, (jint) bytes); + } + break; + case JVM_CONSTANT_Float : + { + cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags + u4 bytes = cfs->get_u4_fast(); + _cp->float_at_put(index, *(jfloat*)&bytes); + } + break; + case JVM_CONSTANT_Long : + // A mangled type might cause you to overrun allocated memory + guarantee_property(index+1 < length, + "Invalid constant pool entry %u in class file %s", + index, CHECK); + { + cfs->guarantee_more(9, CHECK); // bytes, tag/access_flags + u8 bytes = cfs->get_u8_fast(); + _cp->long_at_put(index, bytes); + } + index++; // Skip entry following eigth-byte constant, see JVM book p. 98 + break; + case JVM_CONSTANT_Double : + // A mangled type might cause you to overrun allocated memory + guarantee_property(index+1 < length, + "Invalid constant pool entry %u in class file %s", + index, CHECK); + { + cfs->guarantee_more(9, CHECK); // bytes, tag/access_flags + u8 bytes = cfs->get_u8_fast(); + _cp->double_at_put(index, *(jdouble*)&bytes); + } + index++; // Skip entry following eigth-byte constant, see JVM book p. 98 + break; + case JVM_CONSTANT_NameAndType : + { + cfs->guarantee_more(5, CHECK); // name_index, signature_index, tag/access_flags + u2 name_index = cfs->get_u2_fast(); + u2 signature_index = cfs->get_u2_fast(); + _cp->name_and_type_at_put(index, name_index, signature_index); + } + break; + case JVM_CONSTANT_Utf8 : + { + cfs->guarantee_more(2, CHECK); // utf8_length + u2 utf8_length = cfs->get_u2_fast(); + u1* utf8_buffer = cfs->get_u1_buffer(); + assert(utf8_buffer != NULL, "null utf8 buffer"); + // Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward. + cfs->guarantee_more(utf8_length+1, CHECK); // utf8 string, tag/access_flags + cfs->skip_u1_fast(utf8_length); + + // Before storing the symbol, make sure it's legal + if (_need_verify) { + verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK); + } + + if (has_cp_patch_at(index)) { + Handle patch = clear_cp_patch_at(index); + guarantee_property(java_lang_String::is_instance(patch()), + "Illegal utf8 patch at %d in class file %s", + index, CHECK); + char* str = java_lang_String::as_utf8_string(patch()); + // (could use java_lang_String::as_symbol instead, but might as well batch them) + utf8_buffer = (u1*) str; + utf8_length = (int) strlen(str); + } + + unsigned int hash; + Symbol* result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash); + if (result == NULL) { + names[names_count] = (char*)utf8_buffer; + lengths[names_count] = utf8_length; + indices[names_count] = index; + hashValues[names_count++] = hash; + if (names_count == SymbolTable::symbol_alloc_batch_size) { + SymbolTable::new_symbols(_loader_data, _cp, names_count, names, lengths, indices, hashValues, CHECK); + names_count = 0; + } + } else { + _cp->symbol_at_put(index, result); + } + } + break; + default: + classfile_parse_error( + "Unknown constant tag %u in class file %s", tag, CHECK); + break; + } + } + + // Allocate the remaining symbols + if (names_count > 0) { + SymbolTable::new_symbols(_loader_data, _cp, names_count, names, lengths, indices, hashValues, CHECK); + } + + // Copy _current pointer of local copy back to stream(). +#ifdef ASSERT + assert(cfs0->current() == old_current, "non-exclusive use of stream()"); +#endif + cfs0->set_current(cfs1.current()); +} + +bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); } + +inline Symbol* check_symbol_at(constantPoolHandle cp, int index) { + if (valid_cp_range(index, cp->length()) && cp->tag_at(index).is_utf8()) + return cp->symbol_at(index); + else + return NULL; +} + +constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) { + ClassFileStream* cfs = stream(); + constantPoolHandle nullHandle; + + cfs->guarantee_more(3, CHECK_(nullHandle)); // length, first cp tag + u2 length = cfs->get_u2_fast(); + guarantee_property( + length >= 1, "Illegal constant pool size %u in class file %s", + length, CHECK_(nullHandle)); + ConstantPool* constant_pool = ConstantPool::allocate(_loader_data, length, + CHECK_(nullHandle)); + _cp = constant_pool; // save in case of errors + constantPoolHandle cp (THREAD, constant_pool); + + // parsing constant pool entries + parse_constant_pool_entries(length, CHECK_(nullHandle)); + + int index = 1; // declared outside of loops for portability + + // first verification pass - validate cross references and fixup class and string constants + for (index = 1; index < length; index++) { // Index 0 is unused + jbyte tag = cp->tag_at(index).value(); + switch (tag) { + case JVM_CONSTANT_Class : + ShouldNotReachHere(); // Only JVM_CONSTANT_ClassIndex should be present + break; + case JVM_CONSTANT_Fieldref : + // fall through + case JVM_CONSTANT_Methodref : + // fall through + case JVM_CONSTANT_InterfaceMethodref : { + if (!_need_verify) break; + int klass_ref_index = cp->klass_ref_index_at(index); + int name_and_type_ref_index = cp->name_and_type_ref_index_at(index); + check_property(valid_klass_reference_at(klass_ref_index), + "Invalid constant pool index %u in class file %s", + klass_ref_index, + CHECK_(nullHandle)); + check_property(valid_cp_range(name_and_type_ref_index, length) && + cp->tag_at(name_and_type_ref_index).is_name_and_type(), + "Invalid constant pool index %u in class file %s", + name_and_type_ref_index, + CHECK_(nullHandle)); + break; + } + case JVM_CONSTANT_String : + ShouldNotReachHere(); // Only JVM_CONSTANT_StringIndex should be present + break; + case JVM_CONSTANT_Integer : + break; + case JVM_CONSTANT_Float : + break; + case JVM_CONSTANT_Long : + case JVM_CONSTANT_Double : + index++; + check_property( + (index < length && cp->tag_at(index).is_invalid()), + "Improper constant pool long/double index %u in class file %s", + index, CHECK_(nullHandle)); + break; + case JVM_CONSTANT_NameAndType : { + if (!_need_verify) break; + int name_ref_index = cp->name_ref_index_at(index); + int signature_ref_index = cp->signature_ref_index_at(index); + check_property(valid_symbol_at(name_ref_index), + "Invalid constant pool index %u in class file %s", + name_ref_index, CHECK_(nullHandle)); + check_property(valid_symbol_at(signature_ref_index), + "Invalid constant pool index %u in class file %s", + signature_ref_index, CHECK_(nullHandle)); + break; + } + case JVM_CONSTANT_Utf8 : + break; + case JVM_CONSTANT_UnresolvedClass : // fall-through + case JVM_CONSTANT_UnresolvedClassInError: + ShouldNotReachHere(); // Only JVM_CONSTANT_ClassIndex should be present + break; + case JVM_CONSTANT_ClassIndex : + { + int class_index = cp->klass_index_at(index); + check_property(valid_symbol_at(class_index), + "Invalid constant pool index %u in class file %s", + class_index, CHECK_(nullHandle)); + cp->unresolved_klass_at_put(index, cp->symbol_at(class_index)); + } + break; + case JVM_CONSTANT_StringIndex : + { + int string_index = cp->string_index_at(index); + check_property(valid_symbol_at(string_index), + "Invalid constant pool index %u in class file %s", + string_index, CHECK_(nullHandle)); + Symbol* sym = cp->symbol_at(string_index); + cp->unresolved_string_at_put(index, sym); + } + break; + case JVM_CONSTANT_MethodHandle : + { + int ref_index = cp->method_handle_index_at(index); + check_property( + valid_cp_range(ref_index, length), + "Invalid constant pool index %u in class file %s", + ref_index, CHECK_(nullHandle)); + constantTag tag = cp->tag_at(ref_index); + int ref_kind = cp->method_handle_ref_kind_at(index); + switch (ref_kind) { + case JVM_REF_getField: + case JVM_REF_getStatic: + case JVM_REF_putField: + case JVM_REF_putStatic: + check_property( + tag.is_field(), + "Invalid constant pool index %u in class file %s (not a field)", + ref_index, CHECK_(nullHandle)); + break; + case JVM_REF_invokeVirtual: + case JVM_REF_newInvokeSpecial: + check_property( + tag.is_method(), + "Invalid constant pool index %u in class file %s (not a method)", + ref_index, CHECK_(nullHandle)); + break; + case JVM_REF_invokeStatic: + case JVM_REF_invokeSpecial: + check_property(tag.is_method() || + ((_major_version >= JAVA_8_VERSION) && tag.is_interface_method()), + "Invalid constant pool index %u in class file %s (not a method)", + ref_index, CHECK_(nullHandle)); + break; + case JVM_REF_invokeInterface: + check_property( + tag.is_interface_method(), + "Invalid constant pool index %u in class file %s (not an interface method)", + ref_index, CHECK_(nullHandle)); + break; + default: + classfile_parse_error( + "Bad method handle kind at constant pool index %u in class file %s", + index, CHECK_(nullHandle)); + } + // Keep the ref_index unchanged. It will be indirected at link-time. + } + break; + case JVM_CONSTANT_MethodType : + { + int ref_index = cp->method_type_index_at(index); + check_property(valid_symbol_at(ref_index), + "Invalid constant pool index %u in class file %s", + ref_index, CHECK_(nullHandle)); + } + break; + case JVM_CONSTANT_InvokeDynamic : + { + int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index); + check_property(valid_cp_range(name_and_type_ref_index, length) && + cp->tag_at(name_and_type_ref_index).is_name_and_type(), + "Invalid constant pool index %u in class file %s", + name_and_type_ref_index, + CHECK_(nullHandle)); + // bootstrap specifier index must be checked later, when BootstrapMethods attr is available + break; + } + default: + fatal(err_msg("bad constant pool tag value %u", + cp->tag_at(index).value())); + ShouldNotReachHere(); + break; + } // end of switch + } // end of for + + if (_cp_patches != NULL) { + // need to treat this_class specially... + int this_class_index; + { + cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len + u1* mark = cfs->current(); + u2 flags = cfs->get_u2_fast(); + this_class_index = cfs->get_u2_fast(); + cfs->set_current(mark); // revert to mark + } + + for (index = 1; index < length; index++) { // Index 0 is unused + if (has_cp_patch_at(index)) { + guarantee_property(index != this_class_index, + "Illegal constant pool patch to self at %d in class file %s", + index, CHECK_(nullHandle)); + patch_constant_pool(cp, index, cp_patch_at(index), CHECK_(nullHandle)); + } + } + } + + if (!_need_verify) { + return cp; + } + + // second verification pass - checks the strings are of the right format. + // but not yet to the other entries + for (index = 1; index < length; index++) { + jbyte tag = cp->tag_at(index).value(); + switch (tag) { + case JVM_CONSTANT_UnresolvedClass: { + Symbol* class_name = cp->klass_name_at(index); + // check the name, even if _cp_patches will overwrite it + verify_legal_class_name(class_name, CHECK_(nullHandle)); + break; + } + case JVM_CONSTANT_NameAndType: { + if (_need_verify && _major_version >= JAVA_7_VERSION) { + int sig_index = cp->signature_ref_index_at(index); + int name_index = cp->name_ref_index_at(index); + Symbol* name = cp->symbol_at(name_index); + Symbol* sig = cp->symbol_at(sig_index); + if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) { + verify_legal_method_signature(name, sig, CHECK_(nullHandle)); + } else { + verify_legal_field_signature(name, sig, CHECK_(nullHandle)); + } + } + break; + } + case JVM_CONSTANT_InvokeDynamic: + case JVM_CONSTANT_Fieldref: + case JVM_CONSTANT_Methodref: + case JVM_CONSTANT_InterfaceMethodref: { + int name_and_type_ref_index = cp->name_and_type_ref_index_at(index); + // already verified to be utf8 + int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index); + // already verified to be utf8 + int signature_ref_index = cp->signature_ref_index_at(name_and_type_ref_index); + Symbol* name = cp->symbol_at(name_ref_index); + Symbol* signature = cp->symbol_at(signature_ref_index); + if (tag == JVM_CONSTANT_Fieldref) { + verify_legal_field_name(name, CHECK_(nullHandle)); + if (_need_verify && _major_version >= JAVA_7_VERSION) { + // Signature is verified above, when iterating NameAndType_info. + // Need only to be sure it's the right type. + if (signature->byte_at(0) == JVM_SIGNATURE_FUNC) { + throwIllegalSignature( + "Field", name, signature, CHECK_(nullHandle)); + } + } else { + verify_legal_field_signature(name, signature, CHECK_(nullHandle)); + } + } else { + verify_legal_method_name(name, CHECK_(nullHandle)); + if (_need_verify && _major_version >= JAVA_7_VERSION) { + // Signature is verified above, when iterating NameAndType_info. + // Need only to be sure it's the right type. + if (signature->byte_at(0) != JVM_SIGNATURE_FUNC) { + throwIllegalSignature( + "Method", name, signature, CHECK_(nullHandle)); + } + } else { + verify_legal_method_signature(name, signature, CHECK_(nullHandle)); + } + if (tag == JVM_CONSTANT_Methodref) { + // 4509014: If a class method name begins with '<', it must be "". + assert(name != NULL, "method name in constant pool is null"); + unsigned int name_len = name->utf8_length(); + assert(name_len > 0, "bad method name"); // already verified as legal name + if (name->byte_at(0) == '<') { + if (name != vmSymbols::object_initializer_name()) { + classfile_parse_error( + "Bad method name at constant pool index %u in class file %s", + name_ref_index, CHECK_(nullHandle)); + } + } + } + } + break; + } + case JVM_CONSTANT_MethodHandle: { + int ref_index = cp->method_handle_index_at(index); + int ref_kind = cp->method_handle_ref_kind_at(index); + switch (ref_kind) { + case JVM_REF_invokeVirtual: + case JVM_REF_invokeStatic: + case JVM_REF_invokeSpecial: + case JVM_REF_newInvokeSpecial: + { + int name_and_type_ref_index = cp->name_and_type_ref_index_at(ref_index); + int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index); + Symbol* name = cp->symbol_at(name_ref_index); + if (ref_kind == JVM_REF_newInvokeSpecial) { + if (name != vmSymbols::object_initializer_name()) { + classfile_parse_error( + "Bad constructor name at constant pool index %u in class file %s", + name_ref_index, CHECK_(nullHandle)); + } + } else { + if (name == vmSymbols::object_initializer_name()) { + classfile_parse_error( + "Bad method name at constant pool index %u in class file %s", + name_ref_index, CHECK_(nullHandle)); + } + } + } + break; + // Other ref_kinds are already fully checked in previous pass. + } + break; + } + case JVM_CONSTANT_MethodType: { + Symbol* no_name = vmSymbols::type_name(); // place holder + Symbol* signature = cp->method_type_signature_at(index); + verify_legal_method_signature(no_name, signature, CHECK_(nullHandle)); + break; + } + case JVM_CONSTANT_Utf8: { + assert(cp->symbol_at(index)->refcount() != 0, "count corrupted"); + } + } // end of switch + } // end of for + + return cp; +} + + +void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) { + BasicType patch_type = T_VOID; + + switch (cp->tag_at(index).value()) { + + case JVM_CONSTANT_UnresolvedClass : + // Patching a class means pre-resolving it. + // The name in the constant pool is ignored. + if (java_lang_Class::is_instance(patch())) { + guarantee_property(!java_lang_Class::is_primitive(patch()), + "Illegal class patch at %d in class file %s", + index, CHECK); + cp->klass_at_put(index, java_lang_Class::as_Klass(patch())); + } else { + guarantee_property(java_lang_String::is_instance(patch()), + "Illegal class patch at %d in class file %s", + index, CHECK); + Symbol* name = java_lang_String::as_symbol(patch(), CHECK); + cp->unresolved_klass_at_put(index, name); + } + break; + + case JVM_CONSTANT_String : + // skip this patch and don't clear it. Needs the oop array for resolved + // references to be created first. + return; + + case JVM_CONSTANT_Integer : patch_type = T_INT; goto patch_prim; + case JVM_CONSTANT_Float : patch_type = T_FLOAT; goto patch_prim; + case JVM_CONSTANT_Long : patch_type = T_LONG; goto patch_prim; + case JVM_CONSTANT_Double : patch_type = T_DOUBLE; goto patch_prim; + patch_prim: + { + jvalue value; + BasicType value_type = java_lang_boxing_object::get_value(patch(), &value); + guarantee_property(value_type == patch_type, + "Illegal primitive patch at %d in class file %s", + index, CHECK); + switch (value_type) { + case T_INT: cp->int_at_put(index, value.i); break; + case T_FLOAT: cp->float_at_put(index, value.f); break; + case T_LONG: cp->long_at_put(index, value.j); break; + case T_DOUBLE: cp->double_at_put(index, value.d); break; + default: assert(false, ""); + } + } + break; + + default: + // %%% TODO: put method handles into CONSTANT_InterfaceMethodref, etc. + guarantee_property(!has_cp_patch_at(index), + "Illegal unexpected patch at %d in class file %s", + index, CHECK); + return; + } + + // On fall-through, mark the patch as used. + clear_cp_patch_at(index); +} + + + +class NameSigHash: public ResourceObj { + public: + Symbol* _name; // name + Symbol* _sig; // signature + NameSigHash* _next; // Next entry in hash table +}; + + +#define HASH_ROW_SIZE 256 + +unsigned int hash(Symbol* name, Symbol* sig) { + unsigned int raw_hash = 0; + raw_hash += ((unsigned int)(uintptr_t)name) >> (LogHeapWordSize + 2); + raw_hash += ((unsigned int)(uintptr_t)sig) >> LogHeapWordSize; + + return (raw_hash + (unsigned int)(uintptr_t)name) % HASH_ROW_SIZE; +} + + +void initialize_hashtable(NameSigHash** table) { + memset((void*)table, 0, sizeof(NameSigHash*) * HASH_ROW_SIZE); +} + +// Return false if the name/sig combination is found in table. +// Return true if no duplicate is found. And name/sig is added as a new entry in table. +// The old format checker uses heap sort to find duplicates. +// NOTE: caller should guarantee that GC doesn't happen during the life cycle +// of table since we don't expect Symbol*'s to move. +bool put_after_lookup(Symbol* name, Symbol* sig, NameSigHash** table) { + assert(name != NULL, "name in constant pool is NULL"); + + // First lookup for duplicates + int index = hash(name, sig); + NameSigHash* entry = table[index]; + while (entry != NULL) { + if (entry->_name == name && entry->_sig == sig) { + return false; + } + entry = entry->_next; + } + + // No duplicate is found, allocate a new entry and fill it. + entry = new NameSigHash(); + entry->_name = name; + entry->_sig = sig; + + // Insert into hash table + entry->_next = table[index]; + table[index] = entry; + + return true; +} + + +Array* ClassFileParser::parse_interfaces(int length, + Handle protection_domain, + Symbol* class_name, + bool* has_default_methods, + TRAPS) { + if (length == 0) { + _local_interfaces = Universe::the_empty_klass_array(); + } else { + ClassFileStream* cfs = stream(); + assert(length > 0, "only called for length>0"); + _local_interfaces = MetadataFactory::new_array(_loader_data, length, NULL, CHECK_NULL); + + int index; + for (index = 0; index < length; index++) { + u2 interface_index = cfs->get_u2(CHECK_NULL); + KlassHandle interf; + check_property( + valid_klass_reference_at(interface_index), + "Interface name has bad constant pool index %u in class file %s", + interface_index, CHECK_NULL); + if (_cp->tag_at(interface_index).is_klass()) { + interf = KlassHandle(THREAD, _cp->resolved_klass_at(interface_index)); + } else { + Symbol* unresolved_klass = _cp->klass_name_at(interface_index); + + // Don't need to check legal name because it's checked when parsing constant pool. + // But need to make sure it's not an array type. + guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY, + "Bad interface name in class file %s", CHECK_NULL); + Handle class_loader(THREAD, _loader_data->class_loader()); + + // Call resolve_super so classcircularity is checked + Klass* k = SystemDictionary::resolve_super_or_fail(class_name, + unresolved_klass, class_loader, protection_domain, + false, CHECK_NULL); + interf = KlassHandle(THREAD, k); + } + + if (!interf()->is_interface()) { + THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", NULL); + } + if (InstanceKlass::cast(interf())->has_default_methods()) { + *has_default_methods = true; + } + _local_interfaces->at_put(index, interf()); + } + + if (!_need_verify || length <= 1) { + return _local_interfaces; + } + + // Check if there's any duplicates in interfaces + ResourceMark rm(THREAD); + NameSigHash** interface_names = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, NameSigHash*, HASH_ROW_SIZE); + initialize_hashtable(interface_names); + bool dup = false; + { + debug_only(No_Safepoint_Verifier nsv;) + for (index = 0; index < length; index++) { + Klass* k = _local_interfaces->at(index); + Symbol* name = InstanceKlass::cast(k)->name(); + // If no duplicates, add (name, NULL) in hashtable interface_names. + if (!put_after_lookup(name, NULL, interface_names)) { + dup = true; + break; + } + } + } + if (dup) { + classfile_parse_error("Duplicate interface name in class file %s", CHECK_NULL); + } + } + return _local_interfaces; +} + + +void ClassFileParser::verify_constantvalue(int constantvalue_index, int signature_index, TRAPS) { + // Make sure the constant pool entry is of a type appropriate to this field + guarantee_property( + (constantvalue_index > 0 && + constantvalue_index < _cp->length()), + "Bad initial value index %u in ConstantValue attribute in class file %s", + constantvalue_index, CHECK); + constantTag value_type = _cp->tag_at(constantvalue_index); + switch ( _cp->basic_type_for_signature_at(signature_index) ) { + case T_LONG: + guarantee_property(value_type.is_long(), "Inconsistent constant value type in class file %s", CHECK); + break; + case T_FLOAT: + guarantee_property(value_type.is_float(), "Inconsistent constant value type in class file %s", CHECK); + break; + case T_DOUBLE: + guarantee_property(value_type.is_double(), "Inconsistent constant value type in class file %s", CHECK); + break; + case T_BYTE: case T_CHAR: case T_SHORT: case T_BOOLEAN: case T_INT: + guarantee_property(value_type.is_int(), "Inconsistent constant value type in class file %s", CHECK); + break; + case T_OBJECT: + guarantee_property((_cp->symbol_at(signature_index)->equals("Ljava/lang/String;") + && value_type.is_string()), + "Bad string initial value in class file %s", CHECK); + break; + default: + classfile_parse_error( + "Unable to set initial value %u in class file %s", + constantvalue_index, CHECK); + } +} + + +// Parse attributes for a field. +void ClassFileParser::parse_field_attributes(u2 attributes_count, + bool is_static, u2 signature_index, + u2* constantvalue_index_addr, + bool* is_synthetic_addr, + u2* generic_signature_index_addr, + ClassFileParser::FieldAnnotationCollector* parsed_annotations, + TRAPS) { + ClassFileStream* cfs = stream(); + assert(attributes_count > 0, "length should be greater than 0"); + u2 constantvalue_index = 0; + u2 generic_signature_index = 0; + bool is_synthetic = false; + u1* runtime_visible_annotations = NULL; + int runtime_visible_annotations_length = 0; + u1* runtime_invisible_annotations = NULL; + int runtime_invisible_annotations_length = 0; + u1* runtime_visible_type_annotations = NULL; + int runtime_visible_type_annotations_length = 0; + u1* runtime_invisible_type_annotations = NULL; + int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_annotations_exists = false; + bool runtime_invisible_type_annotations_exists = false; + while (attributes_count--) { + cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length + u2 attribute_name_index = cfs->get_u2_fast(); + u4 attribute_length = cfs->get_u4_fast(); + check_property(valid_symbol_at(attribute_name_index), + "Invalid field attribute index %u in class file %s", + attribute_name_index, + CHECK); + Symbol* attribute_name = _cp->symbol_at(attribute_name_index); + if (is_static && attribute_name == vmSymbols::tag_constant_value()) { + // ignore if non-static + if (constantvalue_index != 0) { + classfile_parse_error("Duplicate ConstantValue attribute in class file %s", CHECK); + } + check_property( + attribute_length == 2, + "Invalid ConstantValue field attribute length %u in class file %s", + attribute_length, CHECK); + constantvalue_index = cfs->get_u2(CHECK); + if (_need_verify) { + verify_constantvalue(constantvalue_index, signature_index, CHECK); + } + } else if (attribute_name == vmSymbols::tag_synthetic()) { + if (attribute_length != 0) { + classfile_parse_error( + "Invalid Synthetic field attribute length %u in class file %s", + attribute_length, CHECK); + } + is_synthetic = true; + } else if (attribute_name == vmSymbols::tag_deprecated()) { // 4276120 + if (attribute_length != 0) { + classfile_parse_error( + "Invalid Deprecated field attribute length %u in class file %s", + attribute_length, CHECK); + } + } else if (_major_version >= JAVA_1_5_VERSION) { + if (attribute_name == vmSymbols::tag_signature()) { + if (attribute_length != 2) { + classfile_parse_error( + "Wrong size %u for field's Signature attribute in class file %s", + attribute_length, CHECK); + } + generic_signature_index = parse_generic_signature_attribute(CHECK); + } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) { + if (runtime_visible_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleAnnotations attributes for field in class file %s", CHECK); + } + runtime_visible_annotations_length = attribute_length; + runtime_visible_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_annotations != NULL, "null visible annotations"); + parse_annotations(runtime_visible_annotations, + runtime_visible_annotations_length, + parsed_annotations, + CHECK); + cfs->skip_u1(runtime_visible_annotations_length, CHECK); + } else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { + if (runtime_invisible_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleAnnotations attributes for field in class file %s", CHECK); + } + runtime_invisible_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_annotations_length = attribute_length; + runtime_invisible_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_annotations != NULL, "null invisible annotations"); + } + cfs->skip_u1(attribute_length, CHECK); + } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { + if (runtime_visible_type_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleTypeAnnotations attributes for field in class file %s", CHECK); + } + runtime_visible_type_annotations_length = attribute_length; + runtime_visible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); + cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); + } else if (attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { + if (runtime_invisible_type_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleTypeAnnotations attributes for field in class file %s", CHECK); + } else { + runtime_invisible_type_annotations_exists = true; + } + if (PreserveAllAnnotations) { + runtime_invisible_type_annotations_length = attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + } + cfs->skip_u1(attribute_length, CHECK); + } else { + cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes + } + } else { + cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes + } + } + + *constantvalue_index_addr = constantvalue_index; + *is_synthetic_addr = is_synthetic; + *generic_signature_index_addr = generic_signature_index; + AnnotationArray* a = assemble_annotations(runtime_visible_annotations, + runtime_visible_annotations_length, + runtime_invisible_annotations, + runtime_invisible_annotations_length, + CHECK); + parsed_annotations->set_field_annotations(a); + a = assemble_annotations(runtime_visible_type_annotations, + runtime_visible_type_annotations_length, + runtime_invisible_type_annotations, + runtime_invisible_type_annotations_length, + CHECK); + parsed_annotations->set_field_type_annotations(a); + return; +} + + +// Field allocation types. Used for computing field offsets. + +enum FieldAllocationType { + STATIC_OOP, // Oops + STATIC_BYTE, // Boolean, Byte, char + STATIC_SHORT, // shorts + STATIC_WORD, // ints + STATIC_DOUBLE, // aligned long or double + NONSTATIC_OOP, + NONSTATIC_BYTE, + NONSTATIC_SHORT, + NONSTATIC_WORD, + NONSTATIC_DOUBLE, + MAX_FIELD_ALLOCATION_TYPE, + BAD_ALLOCATION_TYPE = -1 +}; + +static FieldAllocationType _basic_type_to_atype[2 * (T_CONFLICT + 1)] = { + BAD_ALLOCATION_TYPE, // 0 + BAD_ALLOCATION_TYPE, // 1 + BAD_ALLOCATION_TYPE, // 2 + BAD_ALLOCATION_TYPE, // 3 + NONSTATIC_BYTE , // T_BOOLEAN = 4, + NONSTATIC_SHORT, // T_CHAR = 5, + NONSTATIC_WORD, // T_FLOAT = 6, + NONSTATIC_DOUBLE, // T_DOUBLE = 7, + NONSTATIC_BYTE, // T_BYTE = 8, + NONSTATIC_SHORT, // T_SHORT = 9, + NONSTATIC_WORD, // T_INT = 10, + NONSTATIC_DOUBLE, // T_LONG = 11, + NONSTATIC_OOP, // T_OBJECT = 12, + NONSTATIC_OOP, // T_ARRAY = 13, + BAD_ALLOCATION_TYPE, // T_VOID = 14, + BAD_ALLOCATION_TYPE, // T_ADDRESS = 15, + BAD_ALLOCATION_TYPE, // T_NARROWOOP = 16, + BAD_ALLOCATION_TYPE, // T_METADATA = 17, + BAD_ALLOCATION_TYPE, // T_NARROWKLASS = 18, + BAD_ALLOCATION_TYPE, // T_CONFLICT = 19, + BAD_ALLOCATION_TYPE, // 0 + BAD_ALLOCATION_TYPE, // 1 + BAD_ALLOCATION_TYPE, // 2 + BAD_ALLOCATION_TYPE, // 3 + STATIC_BYTE , // T_BOOLEAN = 4, + STATIC_SHORT, // T_CHAR = 5, + STATIC_WORD, // T_FLOAT = 6, + STATIC_DOUBLE, // T_DOUBLE = 7, + STATIC_BYTE, // T_BYTE = 8, + STATIC_SHORT, // T_SHORT = 9, + STATIC_WORD, // T_INT = 10, + STATIC_DOUBLE, // T_LONG = 11, + STATIC_OOP, // T_OBJECT = 12, + STATIC_OOP, // T_ARRAY = 13, + BAD_ALLOCATION_TYPE, // T_VOID = 14, + BAD_ALLOCATION_TYPE, // T_ADDRESS = 15, + BAD_ALLOCATION_TYPE, // T_NARROWOOP = 16, + BAD_ALLOCATION_TYPE, // T_METADATA = 17, + BAD_ALLOCATION_TYPE, // T_NARROWKLASS = 18, + BAD_ALLOCATION_TYPE, // T_CONFLICT = 19, +}; + +static FieldAllocationType basic_type_to_atype(bool is_static, BasicType type) { + assert(type >= T_BOOLEAN && type < T_VOID, "only allowable values"); + FieldAllocationType result = _basic_type_to_atype[type + (is_static ? (T_CONFLICT + 1) : 0)]; + assert(result != BAD_ALLOCATION_TYPE, "bad type"); + return result; +} + +class FieldAllocationCount: public ResourceObj { + public: + u2 count[MAX_FIELD_ALLOCATION_TYPE]; + + FieldAllocationCount() { + for (int i = 0; i < MAX_FIELD_ALLOCATION_TYPE; i++) { + count[i] = 0; + } + } + + FieldAllocationType update(bool is_static, BasicType type) { + FieldAllocationType atype = basic_type_to_atype(is_static, type); + // Make sure there is no overflow with injected fields. + assert(count[atype] < 0xFFFF, "More than 65535 fields"); + count[atype]++; + return atype; + } +}; + +Array* ClassFileParser::parse_fields(Symbol* class_name, + bool is_interface, + FieldAllocationCount *fac, + u2* java_fields_count_ptr, TRAPS) { + ClassFileStream* cfs = stream(); + cfs->guarantee_more(2, CHECK_NULL); // length + u2 length = cfs->get_u2_fast(); + *java_fields_count_ptr = length; + + int num_injected = 0; + InjectedField* injected = JavaClasses::get_injected(class_name, &num_injected); + int total_fields = length + num_injected; + + // The field array starts with tuples of shorts + // [access, name index, sig index, initial value index, byte offset]. + // A generic signature slot only exists for field with generic + // signature attribute. And the access flag is set with + // JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE for that field. The generic + // signature slots are at the end of the field array and after all + // other fields data. + // + // f1: [access, name index, sig index, initial value index, low_offset, high_offset] + // f2: [access, name index, sig index, initial value index, low_offset, high_offset] + // ... + // fn: [access, name index, sig index, initial value index, low_offset, high_offset] + // [generic signature index] + // [generic signature index] + // ... + // + // Allocate a temporary resource array for field data. For each field, + // a slot is reserved in the temporary array for the generic signature + // index. After parsing all fields, the data are copied to a permanent + // array and any unused slots will be discarded. + ResourceMark rm(THREAD); + u2* fa = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, u2, total_fields * (FieldInfo::field_slots + 1)); + + // The generic signature slots start after all other fields' data. + int generic_signature_slot = total_fields * FieldInfo::field_slots; + int num_generic_signature = 0; + for (int n = 0; n < length; n++) { + cfs->guarantee_more(8, CHECK_NULL); // access_flags, name_index, descriptor_index, attributes_count + + AccessFlags access_flags; + jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_FIELD_MODIFIERS; + verify_legal_field_modifiers(flags, is_interface, CHECK_NULL); + access_flags.set_flags(flags); + + u2 name_index = cfs->get_u2_fast(); + int cp_size = _cp->length(); + check_property(valid_symbol_at(name_index), + "Invalid constant pool index %u for field name in class file %s", + name_index, + CHECK_NULL); + Symbol* name = _cp->symbol_at(name_index); + verify_legal_field_name(name, CHECK_NULL); + + u2 signature_index = cfs->get_u2_fast(); + check_property(valid_symbol_at(signature_index), + "Invalid constant pool index %u for field signature in class file %s", + signature_index, CHECK_NULL); + Symbol* sig = _cp->symbol_at(signature_index); + verify_legal_field_signature(name, sig, CHECK_NULL); + + u2 constantvalue_index = 0; + bool is_synthetic = false; + u2 generic_signature_index = 0; + bool is_static = access_flags.is_static(); + FieldAnnotationCollector parsed_annotations(_loader_data); + + u2 attributes_count = cfs->get_u2_fast(); + if (attributes_count > 0) { + parse_field_attributes(attributes_count, is_static, signature_index, + &constantvalue_index, &is_synthetic, + &generic_signature_index, &parsed_annotations, + CHECK_NULL); + if (parsed_annotations.field_annotations() != NULL) { + if (_fields_annotations == NULL) { + _fields_annotations = MetadataFactory::new_array( + _loader_data, length, NULL, + CHECK_NULL); + } + _fields_annotations->at_put(n, parsed_annotations.field_annotations()); + parsed_annotations.set_field_annotations(NULL); + } + if (parsed_annotations.field_type_annotations() != NULL) { + if (_fields_type_annotations == NULL) { + _fields_type_annotations = MetadataFactory::new_array( + _loader_data, length, NULL, + CHECK_NULL); + } + _fields_type_annotations->at_put(n, parsed_annotations.field_type_annotations()); + parsed_annotations.set_field_type_annotations(NULL); + } + + if (is_synthetic) { + access_flags.set_is_synthetic(); + } + if (generic_signature_index != 0) { + access_flags.set_field_has_generic_signature(); + fa[generic_signature_slot] = generic_signature_index; + generic_signature_slot ++; + num_generic_signature ++; + } + } + + FieldInfo* field = FieldInfo::from_field_array(fa, n); + field->initialize(access_flags.as_short(), + name_index, + signature_index, + constantvalue_index); + BasicType type = _cp->basic_type_for_signature_at(signature_index); + + // Remember how many oops we encountered and compute allocation type + FieldAllocationType atype = fac->update(is_static, type); + field->set_allocation_type(atype); + + // After field is initialized with type, we can augment it with aux info + if (parsed_annotations.has_any_annotations()) + parsed_annotations.apply_to(field); + } + + int index = length; + if (num_injected != 0) { + for (int n = 0; n < num_injected; n++) { + // Check for duplicates + if (injected[n].may_be_java) { + Symbol* name = injected[n].name(); + Symbol* signature = injected[n].signature(); + bool duplicate = false; + for (int i = 0; i < length; i++) { + FieldInfo* f = FieldInfo::from_field_array(fa, i); + if (name == _cp->symbol_at(f->name_index()) && + signature == _cp->symbol_at(f->signature_index())) { + // Symbol is desclared in Java so skip this one + duplicate = true; + break; + } + } + if (duplicate) { + // These will be removed from the field array at the end + continue; + } + } + + // Injected field + FieldInfo* field = FieldInfo::from_field_array(fa, index); + field->initialize(JVM_ACC_FIELD_INTERNAL, + injected[n].name_index, + injected[n].signature_index, + 0); + + BasicType type = FieldType::basic_type(injected[n].signature()); + + // Remember how many oops we encountered and compute allocation type + FieldAllocationType atype = fac->update(false, type); + field->set_allocation_type(atype); + index++; + } + } + + // Now copy the fields' data from the temporary resource array. + // Sometimes injected fields already exist in the Java source so + // the fields array could be too long. In that case the + // fields array is trimed. Also unused slots that were reserved + // for generic signature indexes are discarded. + Array* fields = MetadataFactory::new_array( + _loader_data, index * FieldInfo::field_slots + num_generic_signature, + CHECK_NULL); + _fields = fields; // save in case of error + { + int i = 0; + for (; i < index * FieldInfo::field_slots; i++) { + fields->at_put(i, fa[i]); + } + for (int j = total_fields * FieldInfo::field_slots; + j < generic_signature_slot; j++) { + fields->at_put(i++, fa[j]); + } + assert(i == fields->length(), ""); + } + + if (_need_verify && length > 1) { + // Check duplicated fields + ResourceMark rm(THREAD); + NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, NameSigHash*, HASH_ROW_SIZE); + initialize_hashtable(names_and_sigs); + bool dup = false; + { + debug_only(No_Safepoint_Verifier nsv;) + for (AllFieldStream fs(fields, _cp); !fs.done(); fs.next()) { + Symbol* name = fs.name(); + Symbol* sig = fs.signature(); + // If no duplicates, add name/signature in hashtable names_and_sigs. + if (!put_after_lookup(name, sig, names_and_sigs)) { + dup = true; + break; + } + } + } + if (dup) { + classfile_parse_error("Duplicate field name&signature in class file %s", + CHECK_NULL); + } + } + + return fields; +} + + +static void copy_u2_with_conversion(u2* dest, u2* src, int length) { + while (length-- > 0) { + *dest++ = Bytes::get_Java_u2((u1*) (src++)); + } +} + + +u2* ClassFileParser::parse_exception_table(u4 code_length, + u4 exception_table_length, + TRAPS) { + ClassFileStream* cfs = stream(); + + u2* exception_table_start = cfs->get_u2_buffer(); + assert(exception_table_start != NULL, "null exception table"); + cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc, end_pc, handler_pc, catch_type_index + // Will check legal target after parsing code array in verifier. + if (_need_verify) { + for (unsigned int i = 0; i < exception_table_length; i++) { + u2 start_pc = cfs->get_u2_fast(); + u2 end_pc = cfs->get_u2_fast(); + u2 handler_pc = cfs->get_u2_fast(); + u2 catch_type_index = cfs->get_u2_fast(); + guarantee_property((start_pc < end_pc) && (end_pc <= code_length), + "Illegal exception table range in class file %s", + CHECK_NULL); + guarantee_property(handler_pc < code_length, + "Illegal exception table handler in class file %s", + CHECK_NULL); + if (catch_type_index != 0) { + guarantee_property(valid_klass_reference_at(catch_type_index), + "Catch type in exception table has bad constant type in class file %s", CHECK_NULL); + } + } + } else { + cfs->skip_u2_fast(exception_table_length * 4); + } + return exception_table_start; +} + +void ClassFileParser::parse_linenumber_table( + u4 code_attribute_length, u4 code_length, + CompressedLineNumberWriteStream** write_stream, TRAPS) { + ClassFileStream* cfs = stream(); + unsigned int num_entries = cfs->get_u2(CHECK); + + // Each entry is a u2 start_pc, and a u2 line_number + unsigned int length_in_bytes = num_entries * (sizeof(u2) + sizeof(u2)); + + // Verify line number attribute and table length + check_property( + code_attribute_length == sizeof(u2) + length_in_bytes, + "LineNumberTable attribute has wrong length in class file %s", CHECK); + + cfs->guarantee_more(length_in_bytes, CHECK); + + if ((*write_stream) == NULL) { + if (length_in_bytes > fixed_buffer_size) { + (*write_stream) = new CompressedLineNumberWriteStream(length_in_bytes); + } else { + (*write_stream) = new CompressedLineNumberWriteStream( + linenumbertable_buffer, fixed_buffer_size); + } + } + + while (num_entries-- > 0) { + u2 bci = cfs->get_u2_fast(); // start_pc + u2 line = cfs->get_u2_fast(); // line_number + guarantee_property(bci < code_length, + "Invalid pc in LineNumberTable in class file %s", CHECK); + (*write_stream)->write_pair(bci, line); + } +} + + +// Class file LocalVariableTable elements. +class Classfile_LVT_Element VALUE_OBJ_CLASS_SPEC { + public: + u2 start_bci; + u2 length; + u2 name_cp_index; + u2 descriptor_cp_index; + u2 slot; +}; + + +class LVT_Hash: public CHeapObj { + public: + LocalVariableTableElement *_elem; // element + LVT_Hash* _next; // Next entry in hash table +}; + +unsigned int hash(LocalVariableTableElement *elem) { + unsigned int raw_hash = elem->start_bci; + + raw_hash = elem->length + raw_hash * 37; + raw_hash = elem->name_cp_index + raw_hash * 37; + raw_hash = elem->slot + raw_hash * 37; + + return raw_hash % HASH_ROW_SIZE; +} + +void initialize_hashtable(LVT_Hash** table) { + for (int i = 0; i < HASH_ROW_SIZE; i++) { + table[i] = NULL; + } +} + +void clear_hashtable(LVT_Hash** table) { + for (int i = 0; i < HASH_ROW_SIZE; i++) { + LVT_Hash* current = table[i]; + LVT_Hash* next; + while (current != NULL) { + next = current->_next; + current->_next = NULL; + delete(current); + current = next; + } + table[i] = NULL; + } +} + +LVT_Hash* LVT_lookup(LocalVariableTableElement *elem, int index, LVT_Hash** table) { + LVT_Hash* entry = table[index]; + + /* + * 3-tuple start_bci/length/slot has to be unique key, + * so the following comparison seems to be redundant: + * && elem->name_cp_index == entry->_elem->name_cp_index + */ + while (entry != NULL) { + if (elem->start_bci == entry->_elem->start_bci + && elem->length == entry->_elem->length + && elem->name_cp_index == entry->_elem->name_cp_index + && elem->slot == entry->_elem->slot + ) { + return entry; + } + entry = entry->_next; + } + return NULL; +} + +// Return false if the local variable is found in table. +// Return true if no duplicate is found. +// And local variable is added as a new entry in table. +bool LVT_put_after_lookup(LocalVariableTableElement *elem, LVT_Hash** table) { + // First lookup for duplicates + int index = hash(elem); + LVT_Hash* entry = LVT_lookup(elem, index, table); + + if (entry != NULL) { + return false; + } + // No duplicate is found, allocate a new entry and fill it. + if ((entry = new LVT_Hash()) == NULL) { + return false; + } + entry->_elem = elem; + + // Insert into hash table + entry->_next = table[index]; + table[index] = entry; + + return true; +} + +void copy_lvt_element(Classfile_LVT_Element *src, LocalVariableTableElement *lvt) { + lvt->start_bci = Bytes::get_Java_u2((u1*) &src->start_bci); + lvt->length = Bytes::get_Java_u2((u1*) &src->length); + lvt->name_cp_index = Bytes::get_Java_u2((u1*) &src->name_cp_index); + lvt->descriptor_cp_index = Bytes::get_Java_u2((u1*) &src->descriptor_cp_index); + lvt->signature_cp_index = 0; + lvt->slot = Bytes::get_Java_u2((u1*) &src->slot); +} + +// Function is used to parse both attributes: +// LocalVariableTable (LVT) and LocalVariableTypeTable (LVTT) +u2* ClassFileParser::parse_localvariable_table(u4 code_length, + u2 max_locals, + u4 code_attribute_length, + u2* localvariable_table_length, + bool isLVTT, + TRAPS) { + ClassFileStream* cfs = stream(); + const char * tbl_name = (isLVTT) ? "LocalVariableTypeTable" : "LocalVariableTable"; + *localvariable_table_length = cfs->get_u2(CHECK_NULL); + unsigned int size = (*localvariable_table_length) * sizeof(Classfile_LVT_Element) / sizeof(u2); + // Verify local variable table attribute has right length + if (_need_verify) { + guarantee_property(code_attribute_length == (sizeof(*localvariable_table_length) + size * sizeof(u2)), + "%s has wrong length in class file %s", tbl_name, CHECK_NULL); + } + u2* localvariable_table_start = cfs->get_u2_buffer(); + assert(localvariable_table_start != NULL, "null local variable table"); + if (!_need_verify) { + cfs->skip_u2_fast(size); + } else { + cfs->guarantee_more(size * 2, CHECK_NULL); + for(int i = 0; i < (*localvariable_table_length); i++) { + u2 start_pc = cfs->get_u2_fast(); + u2 length = cfs->get_u2_fast(); + u2 name_index = cfs->get_u2_fast(); + u2 descriptor_index = cfs->get_u2_fast(); + u2 index = cfs->get_u2_fast(); + // Assign to a u4 to avoid overflow + u4 end_pc = (u4)start_pc + (u4)length; + + if (start_pc >= code_length) { + classfile_parse_error( + "Invalid start_pc %u in %s in class file %s", + start_pc, tbl_name, CHECK_NULL); + } + if (end_pc > code_length) { + classfile_parse_error( + "Invalid length %u in %s in class file %s", + length, tbl_name, CHECK_NULL); + } + int cp_size = _cp->length(); + guarantee_property(valid_symbol_at(name_index), + "Name index %u in %s has bad constant type in class file %s", + name_index, tbl_name, CHECK_NULL); + guarantee_property(valid_symbol_at(descriptor_index), + "Signature index %u in %s has bad constant type in class file %s", + descriptor_index, tbl_name, CHECK_NULL); + + Symbol* name = _cp->symbol_at(name_index); + Symbol* sig = _cp->symbol_at(descriptor_index); + verify_legal_field_name(name, CHECK_NULL); + u2 extra_slot = 0; + if (!isLVTT) { + verify_legal_field_signature(name, sig, CHECK_NULL); + + // 4894874: check special cases for double and long local variables + if (sig == vmSymbols::type_signature(T_DOUBLE) || + sig == vmSymbols::type_signature(T_LONG)) { + extra_slot = 1; + } + } + guarantee_property((index + extra_slot) < max_locals, + "Invalid index %u in %s in class file %s", + index, tbl_name, CHECK_NULL); + } + } + return localvariable_table_start; +} + + +void ClassFileParser::parse_type_array(u2 array_length, u4 code_length, u4* u1_index, u4* u2_index, + u1* u1_array, u2* u2_array, TRAPS) { + ClassFileStream* cfs = stream(); + u2 index = 0; // index in the array with long/double occupying two slots + u4 i1 = *u1_index; + u4 i2 = *u2_index + 1; + for(int i = 0; i < array_length; i++) { + u1 tag = u1_array[i1++] = cfs->get_u1(CHECK); + index++; + if (tag == ITEM_Long || tag == ITEM_Double) { + index++; + } else if (tag == ITEM_Object) { + u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK); + guarantee_property(valid_klass_reference_at(class_index), + "Bad class index %u in StackMap in class file %s", + class_index, CHECK); + } else if (tag == ITEM_Uninitialized) { + u2 offset = u2_array[i2++] = cfs->get_u2(CHECK); + guarantee_property( + offset < code_length, + "Bad uninitialized type offset %u in StackMap in class file %s", + offset, CHECK); + } else { + guarantee_property( + tag <= (u1)ITEM_Uninitialized, + "Unknown variable type %u in StackMap in class file %s", + tag, CHECK); + } + } + u2_array[*u2_index] = index; + *u1_index = i1; + *u2_index = i2; +} + +u1* ClassFileParser::parse_stackmap_table( + u4 code_attribute_length, TRAPS) { + if (code_attribute_length == 0) + return NULL; + + ClassFileStream* cfs = stream(); + u1* stackmap_table_start = cfs->get_u1_buffer(); + assert(stackmap_table_start != NULL, "null stackmap table"); + + // check code_attribute_length first + stream()->skip_u1(code_attribute_length, CHECK_NULL); + + if (!_need_verify && !DumpSharedSpaces) { + return NULL; + } + return stackmap_table_start; +} + +u2* ClassFileParser::parse_checked_exceptions(u2* checked_exceptions_length, + u4 method_attribute_length, + TRAPS) { + ClassFileStream* cfs = stream(); + cfs->guarantee_more(2, CHECK_NULL); // checked_exceptions_length + *checked_exceptions_length = cfs->get_u2_fast(); + unsigned int size = (*checked_exceptions_length) * sizeof(CheckedExceptionElement) / sizeof(u2); + u2* checked_exceptions_start = cfs->get_u2_buffer(); + assert(checked_exceptions_start != NULL, "null checked exceptions"); + if (!_need_verify) { + cfs->skip_u2_fast(size); + } else { + // Verify each value in the checked exception table + u2 checked_exception; + u2 len = *checked_exceptions_length; + cfs->guarantee_more(2 * len, CHECK_NULL); + for (int i = 0; i < len; i++) { + checked_exception = cfs->get_u2_fast(); + check_property( + valid_klass_reference_at(checked_exception), + "Exception name has bad type at constant pool %u in class file %s", + checked_exception, CHECK_NULL); + } + } + // check exceptions attribute length + if (_need_verify) { + guarantee_property(method_attribute_length == (sizeof(*checked_exceptions_length) + + sizeof(u2) * size), + "Exceptions attribute has wrong length in class file %s", CHECK_NULL); + } + return checked_exceptions_start; +} + +void ClassFileParser::throwIllegalSignature( + const char* type, Symbol* name, Symbol* sig, TRAPS) { + ResourceMark rm(THREAD); + Exceptions::fthrow(THREAD_AND_LOCATION, + vmSymbols::java_lang_ClassFormatError(), + "%s \"%s\" in class %s has illegal signature \"%s\"", type, + name->as_C_string(), _class_name->as_C_string(), sig->as_C_string()); +} + +// Skip an annotation. Return >=limit if there is any problem. +int ClassFileParser::skip_annotation(u1* buffer, int limit, int index) { + // annotation := atype:u2 do(nmem:u2) {member:u2 value} + // value := switch (tag:u1) { ... } + index += 2; // skip atype + if ((index += 2) >= limit) return limit; // read nmem + int nmem = Bytes::get_Java_u2(buffer+index-2); + while (--nmem >= 0 && index < limit) { + index += 2; // skip member + index = skip_annotation_value(buffer, limit, index); + } + return index; +} + +// Skip an annotation value. Return >=limit if there is any problem. +int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) { + // value := switch (tag:u1) { + // case B, C, I, S, Z, D, F, J, c: con:u2; + // case e: e_class:u2 e_name:u2; + // case s: s_con:u2; + // case [: do(nval:u2) {value}; + // case @: annotation; + // case s: s_con:u2; + // } + if ((index += 1) >= limit) return limit; // read tag + u1 tag = buffer[index-1]; + switch (tag) { + case 'B': case 'C': case 'I': case 'S': case 'Z': + case 'D': case 'F': case 'J': case 'c': case 's': + index += 2; // skip con or s_con + break; + case 'e': + index += 4; // skip e_class, e_name + break; + case '[': + { + if ((index += 2) >= limit) return limit; // read nval + int nval = Bytes::get_Java_u2(buffer+index-2); + while (--nval >= 0 && index < limit) { + index = skip_annotation_value(buffer, limit, index); + } + } + break; + case '@': + index = skip_annotation(buffer, limit, index); + break; + default: + assert(false, "annotation tag"); + return limit; // bad tag byte + } + return index; +} + +// Sift through annotations, looking for those significant to the VM: +void ClassFileParser::parse_annotations(u1* buffer, int limit, + ClassFileParser::AnnotationCollector* coll, + TRAPS) { + // annotations := do(nann:u2) {annotation} + int index = 0; + if ((index += 2) >= limit) return; // read nann + int nann = Bytes::get_Java_u2(buffer+index-2); + enum { // initial annotation layout + atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;' + count_off = 2, // u2 such as 1 (one value) + member_off = 4, // utf8 such as 'value' + tag_off = 6, // u1 such as 'c' (type) or 'e' (enum) + e_tag_val = 'e', + e_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;' + e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME' + e_size = 11, // end of 'e' annotation + c_tag_val = 'c', // payload is type + c_con_off = 7, // utf8 payload, such as 'I' + c_size = 9, // end of 'c' annotation + s_tag_val = 's', // payload is String + s_con_off = 7, // utf8 payload, such as 'Ljava/lang/String;' + s_size = 9, + min_size = 6 // smallest possible size (zero members) + }; + while ((--nann) >= 0 && (index-2 + min_size <= limit)) { + int index0 = index; + index = skip_annotation(buffer, limit, index); + u1* abase = buffer + index0; + int atype = Bytes::get_Java_u2(abase + atype_off); + int count = Bytes::get_Java_u2(abase + count_off); + Symbol* aname = check_symbol_at(_cp, atype); + if (aname == NULL) break; // invalid annotation name + Symbol* member = NULL; + if (count >= 1) { + int member_index = Bytes::get_Java_u2(abase + member_off); + member = check_symbol_at(_cp, member_index); + if (member == NULL) break; // invalid member name + } + + // Here is where parsing particular annotations will take place. + AnnotationCollector::ID id = coll->annotation_index(_loader_data, aname); + if (id == AnnotationCollector::_unknown) continue; + coll->set_annotation(id); + + if (id == AnnotationCollector::_sun_misc_Contended) { + // @Contended can optionally specify the contention group. + // + // Contended group defines the equivalence class over the fields: + // the fields within the same contended group are not treated distinct. + // The only exception is default group, which does not incur the + // equivalence. Naturally, contention group for classes is meaningless. + // + // While the contention group is specified as String, annotation + // values are already interned, and we might as well use the constant + // pool index as the group tag. + // + u2 group_index = 0; // default contended group + if (count == 1 + && s_size == (index - index0) // match size + && s_tag_val == *(abase + tag_off) + && member == vmSymbols::value_name()) { + group_index = Bytes::get_Java_u2(abase + s_con_off); + if (_cp->symbol_at(group_index)->utf8_length() == 0) { + group_index = 0; // default contended group + } + } + coll->set_contended_group(group_index); + } + } +} + +ClassFileParser::AnnotationCollector::ID +ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_data, + Symbol* name) { + vmSymbols::SID sid = vmSymbols::find_sid(name); + // Privileged code can use all annotations. Other code silently drops some. + const bool privileged = loader_data->is_the_null_class_loader_data() || + loader_data->is_ext_class_loader_data() || + loader_data->is_anonymous(); + switch (sid) { + case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_reflect_CallerSensitive_signature): + if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code + return _method_CallerSensitive; + case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature): + if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code + return _method_ForceInline; + case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature): + if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code + return _method_DontInline; + case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature): + if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code + return _method_LambdaForm_Compiled; + case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature): + if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code + return _method_LambdaForm_Hidden; + case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_Stable_signature): + if (_location != _in_field) break; // only allow for fields + if (!privileged) break; // only allow in privileged code + return _field_Stable; + case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_misc_Contended_signature): + if (_location != _in_field && _location != _in_class) break; // only allow for fields and classes + if (!EnableContended || (RestrictContended && !privileged)) break; // honor privileges + return _sun_misc_Contended; + default: break; + } + return AnnotationCollector::_unknown; +} + +void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) { + if (is_contended()) + f->set_contended_group(contended_group()); + if (is_stable()) + f->set_stable(true); +} + +ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector() { + // If there's an error deallocate metadata for field annotations + MetadataFactory::free_array(_loader_data, _field_annotations); + MetadataFactory::free_array(_loader_data, _field_type_annotations); +} + +void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) { + if (has_annotation(_method_CallerSensitive)) + m->set_caller_sensitive(true); + if (has_annotation(_method_ForceInline)) + m->set_force_inline(true); + if (has_annotation(_method_DontInline)) + m->set_dont_inline(true); + if (has_annotation(_method_LambdaForm_Compiled) && m->intrinsic_id() == vmIntrinsics::_none) + m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm); + if (has_annotation(_method_LambdaForm_Hidden)) + m->set_hidden(true); +} + +void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) { + k->set_is_contended(is_contended()); +} + + +#define MAX_ARGS_SIZE 255 +#define MAX_CODE_SIZE 65535 +#define INITIAL_MAX_LVT_NUMBER 256 + +/* Copy class file LVT's/LVTT's into the HotSpot internal LVT. + * + * Rules for LVT's and LVTT's are: + * - There can be any number of LVT's and LVTT's. + * - If there are n LVT's, it is the same as if there was just + * one LVT containing all the entries from the n LVT's. + * - There may be no more than one LVT entry per local variable. + * Two LVT entries are 'equal' if these fields are the same: + * start_pc, length, name, slot + * - There may be no more than one LVTT entry per each LVT entry. + * Each LVTT entry has to match some LVT entry. + * - HotSpot internal LVT keeps natural ordering of class file LVT entries. + */ +void ClassFileParser::copy_localvariable_table(ConstMethod* cm, + int lvt_cnt, + u2* localvariable_table_length, + u2** localvariable_table_start, + int lvtt_cnt, + u2* localvariable_type_table_length, + u2** localvariable_type_table_start, + TRAPS) { + + LVT_Hash** lvt_Hash = NEW_RESOURCE_ARRAY(LVT_Hash*, HASH_ROW_SIZE); + initialize_hashtable(lvt_Hash); + + // To fill LocalVariableTable in + Classfile_LVT_Element* cf_lvt; + LocalVariableTableElement* lvt = cm->localvariable_table_start(); + + for (int tbl_no = 0; tbl_no < lvt_cnt; tbl_no++) { + cf_lvt = (Classfile_LVT_Element *) localvariable_table_start[tbl_no]; + for (int idx = 0; idx < localvariable_table_length[tbl_no]; idx++, lvt++) { + copy_lvt_element(&cf_lvt[idx], lvt); + // If no duplicates, add LVT elem in hashtable lvt_Hash. + if (LVT_put_after_lookup(lvt, lvt_Hash) == false + && _need_verify + && _major_version >= JAVA_1_5_VERSION) { + clear_hashtable(lvt_Hash); + classfile_parse_error("Duplicated LocalVariableTable attribute " + "entry for '%s' in class file %s", + _cp->symbol_at(lvt->name_cp_index)->as_utf8(), + CHECK); + } + } + } + + // To merge LocalVariableTable and LocalVariableTypeTable + Classfile_LVT_Element* cf_lvtt; + LocalVariableTableElement lvtt_elem; + + for (int tbl_no = 0; tbl_no < lvtt_cnt; tbl_no++) { + cf_lvtt = (Classfile_LVT_Element *) localvariable_type_table_start[tbl_no]; + for (int idx = 0; idx < localvariable_type_table_length[tbl_no]; idx++) { + copy_lvt_element(&cf_lvtt[idx], &lvtt_elem); + int index = hash(&lvtt_elem); + LVT_Hash* entry = LVT_lookup(&lvtt_elem, index, lvt_Hash); + if (entry == NULL) { + if (_need_verify) { + clear_hashtable(lvt_Hash); + classfile_parse_error("LVTT entry for '%s' in class file %s " + "does not match any LVT entry", + _cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(), + CHECK); + } + } else if (entry->_elem->signature_cp_index != 0 && _need_verify) { + clear_hashtable(lvt_Hash); + classfile_parse_error("Duplicated LocalVariableTypeTable attribute " + "entry for '%s' in class file %s", + _cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(), + CHECK); + } else { + // to add generic signatures into LocalVariableTable + entry->_elem->signature_cp_index = lvtt_elem.descriptor_cp_index; + } + } + } + clear_hashtable(lvt_Hash); +} + + +void ClassFileParser::copy_method_annotations(ConstMethod* cm, + u1* runtime_visible_annotations, + int runtime_visible_annotations_length, + u1* runtime_invisible_annotations, + int runtime_invisible_annotations_length, + u1* runtime_visible_parameter_annotations, + int runtime_visible_parameter_annotations_length, + u1* runtime_invisible_parameter_annotations, + int runtime_invisible_parameter_annotations_length, + u1* runtime_visible_type_annotations, + int runtime_visible_type_annotations_length, + u1* runtime_invisible_type_annotations, + int runtime_invisible_type_annotations_length, + u1* annotation_default, + int annotation_default_length, + TRAPS) { + + AnnotationArray* a; + + if (runtime_visible_annotations_length + + runtime_invisible_annotations_length > 0) { + a = assemble_annotations(runtime_visible_annotations, + runtime_visible_annotations_length, + runtime_invisible_annotations, + runtime_invisible_annotations_length, + CHECK); + cm->set_method_annotations(a); + } + + if (runtime_visible_parameter_annotations_length + + runtime_invisible_parameter_annotations_length > 0) { + a = assemble_annotations(runtime_visible_parameter_annotations, + runtime_visible_parameter_annotations_length, + runtime_invisible_parameter_annotations, + runtime_invisible_parameter_annotations_length, + CHECK); + cm->set_parameter_annotations(a); + } + + if (annotation_default_length > 0) { + a = assemble_annotations(annotation_default, + annotation_default_length, + NULL, + 0, + CHECK); + cm->set_default_annotations(a); + } + + if (runtime_visible_type_annotations_length + + runtime_invisible_type_annotations_length > 0) { + a = assemble_annotations(runtime_visible_type_annotations, + runtime_visible_type_annotations_length, + runtime_invisible_type_annotations, + runtime_invisible_type_annotations_length, + CHECK); + cm->set_type_annotations(a); + } +} + + +// Note: the parse_method below is big and clunky because all parsing of the code and exceptions +// attribute is inlined. This is cumbersome to avoid since we inline most of the parts in the +// Method* to save footprint, so we only know the size of the resulting Method* when the +// entire method attribute is parsed. +// +// The promoted_flags parameter is used to pass relevant access_flags +// from the method back up to the containing klass. These flag values +// are added to klass's access_flags. + +methodHandle ClassFileParser::parse_method(bool is_interface, + AccessFlags *promoted_flags, + TRAPS) { + ClassFileStream* cfs = stream(); + methodHandle nullHandle; + ResourceMark rm(THREAD); + // Parse fixed parts + cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count + + int flags = cfs->get_u2_fast(); + u2 name_index = cfs->get_u2_fast(); + int cp_size = _cp->length(); + check_property( + valid_symbol_at(name_index), + "Illegal constant pool index %u for method name in class file %s", + name_index, CHECK_(nullHandle)); + Symbol* name = _cp->symbol_at(name_index); + verify_legal_method_name(name, CHECK_(nullHandle)); + + u2 signature_index = cfs->get_u2_fast(); + guarantee_property( + valid_symbol_at(signature_index), + "Illegal constant pool index %u for method signature in class file %s", + signature_index, CHECK_(nullHandle)); + Symbol* signature = _cp->symbol_at(signature_index); + + AccessFlags access_flags; + if (name == vmSymbols::class_initializer_name()) { + // We ignore the other access flags for a valid class initializer. + // (JVM Spec 2nd ed., chapter 4.6) + if (_major_version < 51) { // backward compatibility + flags = JVM_ACC_STATIC; + } else if ((flags & JVM_ACC_STATIC) == JVM_ACC_STATIC) { + flags &= JVM_ACC_STATIC | JVM_ACC_STRICT; + } + } else { + verify_legal_method_modifiers(flags, is_interface, name, CHECK_(nullHandle)); + } + + int args_size = -1; // only used when _need_verify is true + if (_need_verify) { + args_size = ((flags & JVM_ACC_STATIC) ? 0 : 1) + + verify_legal_method_signature(name, signature, CHECK_(nullHandle)); + if (args_size > MAX_ARGS_SIZE) { + classfile_parse_error("Too many arguments in method signature in class file %s", CHECK_(nullHandle)); + } + } + + access_flags.set_flags(flags & JVM_RECOGNIZED_METHOD_MODIFIERS); + + // Default values for code and exceptions attribute elements + u2 max_stack = 0; + u2 max_locals = 0; + u4 code_length = 0; + u1* code_start = 0; + u2 exception_table_length = 0; + u2* exception_table_start = NULL; + Array* exception_handlers = Universe::the_empty_int_array(); + u2 checked_exceptions_length = 0; + u2* checked_exceptions_start = NULL; + CompressedLineNumberWriteStream* linenumber_table = NULL; + int linenumber_table_length = 0; + int total_lvt_length = 0; + u2 lvt_cnt = 0; + u2 lvtt_cnt = 0; + bool lvt_allocated = false; + u2 max_lvt_cnt = INITIAL_MAX_LVT_NUMBER; + u2 max_lvtt_cnt = INITIAL_MAX_LVT_NUMBER; + u2* localvariable_table_length; + u2** localvariable_table_start; + u2* localvariable_type_table_length; + u2** localvariable_type_table_start; + u2 method_parameters_length = 0; + u1* method_parameters_data = NULL; + bool method_parameters_seen = false; + bool parsed_code_attribute = false; + bool parsed_checked_exceptions_attribute = false; + bool parsed_stackmap_attribute = false; + // stackmap attribute - JDK1.5 + u1* stackmap_data = NULL; + int stackmap_data_length = 0; + u2 generic_signature_index = 0; + MethodAnnotationCollector parsed_annotations; + u1* runtime_visible_annotations = NULL; + int runtime_visible_annotations_length = 0; + u1* runtime_invisible_annotations = NULL; + int runtime_invisible_annotations_length = 0; + u1* runtime_visible_parameter_annotations = NULL; + int runtime_visible_parameter_annotations_length = 0; + u1* runtime_invisible_parameter_annotations = NULL; + int runtime_invisible_parameter_annotations_length = 0; + u1* runtime_visible_type_annotations = NULL; + int runtime_visible_type_annotations_length = 0; + u1* runtime_invisible_type_annotations = NULL; + int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_annotations_exists = false; + bool runtime_invisible_type_annotations_exists = false; + bool runtime_invisible_parameter_annotations_exists = false; + u1* annotation_default = NULL; + int annotation_default_length = 0; + + // Parse code and exceptions attribute + u2 method_attributes_count = cfs->get_u2_fast(); + while (method_attributes_count--) { + cfs->guarantee_more(6, CHECK_(nullHandle)); // method_attribute_name_index, method_attribute_length + u2 method_attribute_name_index = cfs->get_u2_fast(); + u4 method_attribute_length = cfs->get_u4_fast(); + check_property( + valid_symbol_at(method_attribute_name_index), + "Invalid method attribute name index %u in class file %s", + method_attribute_name_index, CHECK_(nullHandle)); + + Symbol* method_attribute_name = _cp->symbol_at(method_attribute_name_index); + if (method_attribute_name == vmSymbols::tag_code()) { + // Parse Code attribute + if (_need_verify) { + guarantee_property( + !access_flags.is_native() && !access_flags.is_abstract(), + "Code attribute in native or abstract methods in class file %s", + CHECK_(nullHandle)); + } + if (parsed_code_attribute) { + classfile_parse_error("Multiple Code attributes in class file %s", CHECK_(nullHandle)); + } + parsed_code_attribute = true; + + // Stack size, locals size, and code size + if (_major_version == 45 && _minor_version <= 2) { + cfs->guarantee_more(4, CHECK_(nullHandle)); + max_stack = cfs->get_u1_fast(); + max_locals = cfs->get_u1_fast(); + code_length = cfs->get_u2_fast(); + } else { + cfs->guarantee_more(8, CHECK_(nullHandle)); + max_stack = cfs->get_u2_fast(); + max_locals = cfs->get_u2_fast(); + code_length = cfs->get_u4_fast(); + } + if (_need_verify) { + guarantee_property(args_size <= max_locals, + "Arguments can't fit into locals in class file %s", CHECK_(nullHandle)); + guarantee_property(code_length > 0 && code_length <= MAX_CODE_SIZE, + "Invalid method Code length %u in class file %s", + code_length, CHECK_(nullHandle)); + } + // Code pointer + code_start = cfs->get_u1_buffer(); + assert(code_start != NULL, "null code start"); + cfs->guarantee_more(code_length, CHECK_(nullHandle)); + cfs->skip_u1_fast(code_length); + + // Exception handler table + cfs->guarantee_more(2, CHECK_(nullHandle)); // exception_table_length + exception_table_length = cfs->get_u2_fast(); + if (exception_table_length > 0) { + exception_table_start = + parse_exception_table(code_length, exception_table_length, CHECK_(nullHandle)); + } + + // Parse additional attributes in code attribute + cfs->guarantee_more(2, CHECK_(nullHandle)); // code_attributes_count + u2 code_attributes_count = cfs->get_u2_fast(); + + unsigned int calculated_attribute_length = 0; + + if (_major_version > 45 || (_major_version == 45 && _minor_version > 2)) { + calculated_attribute_length = + sizeof(max_stack) + sizeof(max_locals) + sizeof(code_length); + } else { + // max_stack, locals and length are smaller in pre-version 45.2 classes + calculated_attribute_length = sizeof(u1) + sizeof(u1) + sizeof(u2); + } + calculated_attribute_length += + code_length + + sizeof(exception_table_length) + + sizeof(code_attributes_count) + + exception_table_length * + ( sizeof(u2) + // start_pc + sizeof(u2) + // end_pc + sizeof(u2) + // handler_pc + sizeof(u2) ); // catch_type_index + + while (code_attributes_count--) { + cfs->guarantee_more(6, CHECK_(nullHandle)); // code_attribute_name_index, code_attribute_length + u2 code_attribute_name_index = cfs->get_u2_fast(); + u4 code_attribute_length = cfs->get_u4_fast(); + calculated_attribute_length += code_attribute_length + + sizeof(code_attribute_name_index) + + sizeof(code_attribute_length); + check_property(valid_symbol_at(code_attribute_name_index), + "Invalid code attribute name index %u in class file %s", + code_attribute_name_index, + CHECK_(nullHandle)); + if (LoadLineNumberTables && + _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_line_number_table()) { + // Parse and compress line number table + parse_linenumber_table(code_attribute_length, code_length, + &linenumber_table, CHECK_(nullHandle)); + + } else if (LoadLocalVariableTables && + _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_table()) { + // Parse local variable table + if (!lvt_allocated) { + localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, u2, INITIAL_MAX_LVT_NUMBER); + localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, u2*, INITIAL_MAX_LVT_NUMBER); + localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, u2, INITIAL_MAX_LVT_NUMBER); + localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, u2*, INITIAL_MAX_LVT_NUMBER); + lvt_allocated = true; + } + if (lvt_cnt == max_lvt_cnt) { + max_lvt_cnt <<= 1; + localvariable_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt); + localvariable_table_start = REALLOC_RESOURCE_ARRAY(u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt); + } + localvariable_table_start[lvt_cnt] = + parse_localvariable_table(code_length, + max_locals, + code_attribute_length, + &localvariable_table_length[lvt_cnt], + false, // is not LVTT + CHECK_(nullHandle)); + total_lvt_length += localvariable_table_length[lvt_cnt]; + lvt_cnt++; + } else if (LoadLocalVariableTypeTables && + _major_version >= JAVA_1_5_VERSION && + _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_type_table()) { + if (!lvt_allocated) { + localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, u2, INITIAL_MAX_LVT_NUMBER); + localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, u2*, INITIAL_MAX_LVT_NUMBER); + localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, u2, INITIAL_MAX_LVT_NUMBER); + localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, u2*, INITIAL_MAX_LVT_NUMBER); + lvt_allocated = true; + } + // Parse local variable type table + if (lvtt_cnt == max_lvtt_cnt) { + max_lvtt_cnt <<= 1; + localvariable_type_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt); + localvariable_type_table_start = REALLOC_RESOURCE_ARRAY(u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt); + } + localvariable_type_table_start[lvtt_cnt] = + parse_localvariable_table(code_length, + max_locals, + code_attribute_length, + &localvariable_type_table_length[lvtt_cnt], + true, // is LVTT + CHECK_(nullHandle)); + lvtt_cnt++; + } else if (_major_version >= Verifier::STACKMAP_ATTRIBUTE_MAJOR_VERSION && + _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_stack_map_table()) { + // Stack map is only needed by the new verifier in JDK1.5. + if (parsed_stackmap_attribute) { + classfile_parse_error("Multiple StackMapTable attributes in class file %s", CHECK_(nullHandle)); + } + stackmap_data = parse_stackmap_table(code_attribute_length, CHECK_(nullHandle)); + stackmap_data_length = code_attribute_length; + parsed_stackmap_attribute = true; + } else { + // Skip unknown attributes + cfs->skip_u1(code_attribute_length, CHECK_(nullHandle)); + } + } + // check method attribute length + if (_need_verify) { + guarantee_property(method_attribute_length == calculated_attribute_length, + "Code segment has wrong length in class file %s", CHECK_(nullHandle)); + } + } else if (method_attribute_name == vmSymbols::tag_exceptions()) { + // Parse Exceptions attribute + if (parsed_checked_exceptions_attribute) { + classfile_parse_error("Multiple Exceptions attributes in class file %s", CHECK_(nullHandle)); + } + parsed_checked_exceptions_attribute = true; + checked_exceptions_start = + parse_checked_exceptions(&checked_exceptions_length, + method_attribute_length, + CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_method_parameters()) { + // reject multiple method parameters + if (method_parameters_seen) { + classfile_parse_error("Multiple MethodParameters attributes in class file %s", CHECK_(nullHandle)); + } + method_parameters_seen = true; + method_parameters_length = cfs->get_u1_fast(); + if (method_attribute_length != (method_parameters_length * 4u) + 1u) { + classfile_parse_error( + "Invalid MethodParameters method attribute length %u in class file", + method_attribute_length, CHECK_(nullHandle)); + } + method_parameters_data = cfs->get_u1_buffer(); + cfs->skip_u2_fast(method_parameters_length); + cfs->skip_u2_fast(method_parameters_length); + // ignore this attribute if it cannot be reflected + if (!SystemDictionary::Parameter_klass_loaded()) + method_parameters_length = 0; + } else if (method_attribute_name == vmSymbols::tag_synthetic()) { + if (method_attribute_length != 0) { + classfile_parse_error( + "Invalid Synthetic method attribute length %u in class file %s", + method_attribute_length, CHECK_(nullHandle)); + } + // Should we check that there hasn't already been a synthetic attribute? + access_flags.set_is_synthetic(); + } else if (method_attribute_name == vmSymbols::tag_deprecated()) { // 4276120 + if (method_attribute_length != 0) { + classfile_parse_error( + "Invalid Deprecated method attribute length %u in class file %s", + method_attribute_length, CHECK_(nullHandle)); + } + } else if (_major_version >= JAVA_1_5_VERSION) { + if (method_attribute_name == vmSymbols::tag_signature()) { + if (method_attribute_length != 2) { + classfile_parse_error( + "Invalid Signature attribute length %u in class file %s", + method_attribute_length, CHECK_(nullHandle)); + } + generic_signature_index = parse_generic_signature_attribute(CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) { + if (runtime_visible_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } + runtime_visible_annotations_length = method_attribute_length; + runtime_visible_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_annotations != NULL, "null visible annotations"); + parse_annotations(runtime_visible_annotations, + runtime_visible_annotations_length, &parsed_annotations, + CHECK_(nullHandle)); + cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { + if (runtime_invisible_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } + runtime_invisible_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_annotations_length = method_attribute_length; + runtime_invisible_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_annotations != NULL, "null invisible annotations"); + } + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_visible_parameter_annotations()) { + if (runtime_visible_parameter_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleParameterAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } + runtime_visible_parameter_annotations_length = method_attribute_length; + runtime_visible_parameter_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_parameter_annotations != NULL, "null visible parameter annotations"); + cfs->skip_u1(runtime_visible_parameter_annotations_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_parameter_annotations()) { + if (runtime_invisible_parameter_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleParameterAnnotations attributes for method in class file %s", CHECK_(nullHandle)); + } + runtime_invisible_parameter_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_parameter_annotations_length = method_attribute_length; + runtime_invisible_parameter_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_parameter_annotations != NULL, "null invisible parameter annotations"); + } + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_annotation_default()) { + if (annotation_default != NULL) { + classfile_parse_error( + "Multiple AnnotationDefault attributes for method in class file %s", + CHECK_(nullHandle)); + } + annotation_default_length = method_attribute_length; + annotation_default = cfs->get_u1_buffer(); + assert(annotation_default != NULL, "null annotation default"); + cfs->skip_u1(annotation_default_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { + if (runtime_visible_type_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleTypeAnnotations attributes for method in class file %s", + CHECK_(nullHandle)); + } + runtime_visible_type_annotations_length = method_attribute_length; + runtime_visible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); + // No need for the VM to parse Type annotations + cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { + if (runtime_invisible_type_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleTypeAnnotations attributes for method in class file %s", + CHECK_(nullHandle)); + } else { + runtime_invisible_type_annotations_exists = true; + } + if (PreserveAllAnnotations) { + runtime_invisible_type_annotations_length = method_attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + } + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); + } else { + // Skip unknown attributes + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); + } + } else { + // Skip unknown attributes + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); + } + } + + if (linenumber_table != NULL) { + linenumber_table->write_terminator(); + linenumber_table_length = linenumber_table->position(); + } + + // Make sure there's at least one Code attribute in non-native/non-abstract method + if (_need_verify) { + guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute, + "Absent Code attribute in method that is not native or abstract in class file %s", CHECK_(nullHandle)); + } + + // All sizing information for a Method* is finally available, now create it + InlineTableSizes sizes( + total_lvt_length, + linenumber_table_length, + exception_table_length, + checked_exceptions_length, + method_parameters_length, + generic_signature_index, + runtime_visible_annotations_length + + runtime_invisible_annotations_length, + runtime_visible_parameter_annotations_length + + runtime_invisible_parameter_annotations_length, + runtime_visible_type_annotations_length + + runtime_invisible_type_annotations_length, + annotation_default_length, + 0); + + Method* m = Method::allocate( + _loader_data, code_length, access_flags, &sizes, + ConstMethod::NORMAL, CHECK_(nullHandle)); + + ClassLoadingService::add_class_method_size(m->size()*HeapWordSize); + + // Fill in information from fixed part (access_flags already set) + m->set_constants(_cp); + m->set_name_index(name_index); + m->set_signature_index(signature_index); +#ifdef CC_INTERP + // hmm is there a gc issue here?? + ResultTypeFinder rtf(_cp->symbol_at(signature_index)); + m->set_result_index(rtf.type()); +#endif + + if (args_size >= 0) { + m->set_size_of_parameters(args_size); + } else { + m->compute_size_of_parameters(THREAD); + } +#ifdef ASSERT + if (args_size >= 0) { + m->compute_size_of_parameters(THREAD); + assert(args_size == m->size_of_parameters(), ""); + } +#endif + + // Fill in code attribute information + m->set_max_stack(max_stack); + m->set_max_locals(max_locals); + if (stackmap_data != NULL) { + m->constMethod()->copy_stackmap_data(_loader_data, stackmap_data, + stackmap_data_length, CHECK_NULL); + } + + // Copy byte codes + m->set_code(code_start); + + // Copy line number table + if (linenumber_table != NULL) { + memcpy(m->compressed_linenumber_table(), + linenumber_table->buffer(), linenumber_table_length); + } + + // Copy exception table + if (exception_table_length > 0) { + int size = + exception_table_length * sizeof(ExceptionTableElement) / sizeof(u2); + copy_u2_with_conversion((u2*) m->exception_table_start(), + exception_table_start, size); + } + + // Copy method parameters + if (method_parameters_length > 0) { + MethodParametersElement* elem = m->constMethod()->method_parameters_start(); + for (int i = 0; i < method_parameters_length; i++) { + elem[i].name_cp_index = Bytes::get_Java_u2(method_parameters_data); + method_parameters_data += 2; + elem[i].flags = Bytes::get_Java_u2(method_parameters_data); + method_parameters_data += 2; + } + } + + // Copy checked exceptions + if (checked_exceptions_length > 0) { + int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); + copy_u2_with_conversion((u2*) m->checked_exceptions_start(), checked_exceptions_start, size); + } + + // Copy class file LVT's/LVTT's into the HotSpot internal LVT. + if (total_lvt_length > 0) { + promoted_flags->set_has_localvariable_table(); + copy_localvariable_table(m->constMethod(), lvt_cnt, + localvariable_table_length, + localvariable_table_start, + lvtt_cnt, + localvariable_type_table_length, + localvariable_type_table_start, CHECK_NULL); + } + + if (parsed_annotations.has_any_annotations()) + parsed_annotations.apply_to(m); + + // Copy annotations + copy_method_annotations(m->constMethod(), + runtime_visible_annotations, + runtime_visible_annotations_length, + runtime_invisible_annotations, + runtime_invisible_annotations_length, + runtime_visible_parameter_annotations, + runtime_visible_parameter_annotations_length, + runtime_invisible_parameter_annotations, + runtime_invisible_parameter_annotations_length, + runtime_visible_type_annotations, + runtime_visible_type_annotations_length, + runtime_invisible_type_annotations, + runtime_invisible_type_annotations_length, + annotation_default, + annotation_default_length, + CHECK_NULL); + + if (name == vmSymbols::finalize_method_name() && + signature == vmSymbols::void_method_signature()) { + if (m->is_empty_method()) { + _has_empty_finalizer = true; + } else { + _has_finalizer = true; + } + } + if (name == vmSymbols::object_initializer_name() && + signature == vmSymbols::void_method_signature() && + m->is_vanilla_constructor()) { + _has_vanilla_constructor = true; + } + + NOT_PRODUCT(m->verify()); + return m; +} + + +// The promoted_flags parameter is used to pass relevant access_flags +// from the methods back up to the containing klass. These flag values +// are added to klass's access_flags. + +Array* ClassFileParser::parse_methods(bool is_interface, + AccessFlags* promoted_flags, + bool* has_final_method, + bool* has_default_methods, + TRAPS) { + ClassFileStream* cfs = stream(); + cfs->guarantee_more(2, CHECK_NULL); // length + u2 length = cfs->get_u2_fast(); + if (length == 0) { + _methods = Universe::the_empty_method_array(); + } else { + _methods = MetadataFactory::new_array(_loader_data, length, NULL, CHECK_NULL); + + HandleMark hm(THREAD); + for (int index = 0; index < length; index++) { + methodHandle method = parse_method(is_interface, + promoted_flags, + CHECK_NULL); + + if (method->is_final()) { + *has_final_method = true; + } + if (is_interface && !(*has_default_methods) + && !method->is_abstract() && !method->is_static() + && !method->is_private()) { + // default method + *has_default_methods = true; + } + _methods->at_put(index, method()); + } + + if (_need_verify && length > 1) { + // Check duplicated methods + ResourceMark rm(THREAD); + NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, NameSigHash*, HASH_ROW_SIZE); + initialize_hashtable(names_and_sigs); + bool dup = false; + { + debug_only(No_Safepoint_Verifier nsv;) + for (int i = 0; i < length; i++) { + Method* m = _methods->at(i); + // If no duplicates, add name/signature in hashtable names_and_sigs. + if (!put_after_lookup(m->name(), m->signature(), names_and_sigs)) { + dup = true; + break; + } + } + } + if (dup) { + classfile_parse_error("Duplicate method name&signature in class file %s", + CHECK_NULL); + } + } + } + return _methods; +} + + +intArray* ClassFileParser::sort_methods(Array* methods) { + int length = methods->length(); + // If JVMTI original method ordering or sharing is enabled we have to + // remember the original class file ordering. + // We temporarily use the vtable_index field in the Method* to store the + // class file index, so we can read in after calling qsort. + // Put the method ordering in the shared archive. + if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) { + for (int index = 0; index < length; index++) { + Method* m = methods->at(index); + assert(!m->valid_vtable_index(), "vtable index should not be set"); + m->set_vtable_index(index); + } + } + // Sort method array by ascending method name (for faster lookups & vtable construction) + // Note that the ordering is not alphabetical, see Symbol::fast_compare + Method::sort_methods(methods); + + intArray* method_ordering = NULL; + // If JVMTI original method ordering or sharing is enabled construct int + // array remembering the original ordering + if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) { + method_ordering = new intArray(length); + for (int index = 0; index < length; index++) { + Method* m = methods->at(index); + int old_index = m->vtable_index(); + assert(old_index >= 0 && old_index < length, "invalid method index"); + method_ordering->at_put(index, old_index); + m->set_vtable_index(Method::invalid_vtable_index); + } + } + return method_ordering; +} + +// Parse generic_signature attribute for methods and fields +u2 ClassFileParser::parse_generic_signature_attribute(TRAPS) { + ClassFileStream* cfs = stream(); + cfs->guarantee_more(2, CHECK_0); // generic_signature_index + u2 generic_signature_index = cfs->get_u2_fast(); + check_property( + valid_symbol_at(generic_signature_index), + "Invalid Signature attribute at constant pool index %u in class file %s", + generic_signature_index, CHECK_0); + return generic_signature_index; +} + +void ClassFileParser::parse_classfile_sourcefile_attribute(TRAPS) { + ClassFileStream* cfs = stream(); + cfs->guarantee_more(2, CHECK); // sourcefile_index + u2 sourcefile_index = cfs->get_u2_fast(); + check_property( + valid_symbol_at(sourcefile_index), + "Invalid SourceFile attribute at constant pool index %u in class file %s", + sourcefile_index, CHECK); + set_class_sourcefile_index(sourcefile_index); +} + + + +void ClassFileParser::parse_classfile_source_debug_extension_attribute(int length, TRAPS) { + ClassFileStream* cfs = stream(); + u1* sde_buffer = cfs->get_u1_buffer(); + assert(sde_buffer != NULL, "null sde buffer"); + + // Don't bother storing it if there is no way to retrieve it + if (JvmtiExport::can_get_source_debug_extension()) { + assert((length+1) > length, "Overflow checking"); + u1* sde = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, u1, length+1); + for (int i = 0; i < length; i++) { + sde[i] = sde_buffer[i]; + } + sde[length] = '\0'; + set_class_sde_buffer((char*)sde, length); + } + // Got utf8 string, set stream position forward + cfs->skip_u1(length, CHECK); +} + + +// Inner classes can be static, private or protected (classic VM does this) +#define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC) + +// Return number of classes in the inner classes attribute table +u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start, + bool parsed_enclosingmethod_attribute, + u2 enclosing_method_class_index, + u2 enclosing_method_method_index, + TRAPS) { + ClassFileStream* cfs = stream(); + u1* current_mark = cfs->current(); + u2 length = 0; + if (inner_classes_attribute_start != NULL) { + cfs->set_current(inner_classes_attribute_start); + cfs->guarantee_more(2, CHECK_0); // length + length = cfs->get_u2_fast(); + } + + // 4-tuples of shorts of inner classes data and 2 shorts of enclosing + // method data: + // [inner_class_info_index, + // outer_class_info_index, + // inner_name_index, + // inner_class_access_flags, + // ... + // enclosing_method_class_index, + // enclosing_method_method_index] + int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0); + Array* inner_classes = MetadataFactory::new_array(_loader_data, size, CHECK_0); + _inner_classes = inner_classes; + + int index = 0; + int cp_size = _cp->length(); + cfs->guarantee_more(8 * length, CHECK_0); // 4-tuples of u2 + for (int n = 0; n < length; n++) { + // Inner class index + u2 inner_class_info_index = cfs->get_u2_fast(); + check_property( + inner_class_info_index == 0 || + valid_klass_reference_at(inner_class_info_index), + "inner_class_info_index %u has bad constant type in class file %s", + inner_class_info_index, CHECK_0); + // Outer class index + u2 outer_class_info_index = cfs->get_u2_fast(); + check_property( + outer_class_info_index == 0 || + valid_klass_reference_at(outer_class_info_index), + "outer_class_info_index %u has bad constant type in class file %s", + outer_class_info_index, CHECK_0); + // Inner class name + u2 inner_name_index = cfs->get_u2_fast(); + check_property( + inner_name_index == 0 || valid_symbol_at(inner_name_index), + "inner_name_index %u has bad constant type in class file %s", + inner_name_index, CHECK_0); + if (_need_verify) { + guarantee_property(inner_class_info_index != outer_class_info_index, + "Class is both outer and inner class in class file %s", CHECK_0); + } + // Access flags + AccessFlags inner_access_flags; + jint flags = cfs->get_u2_fast() & RECOGNIZED_INNER_CLASS_MODIFIERS; + if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) { + // Set abstract bit for old class files for backward compatibility + flags |= JVM_ACC_ABSTRACT; + } + verify_legal_class_modifiers(flags, CHECK_0); + inner_access_flags.set_flags(flags); + + inner_classes->at_put(index++, inner_class_info_index); + inner_classes->at_put(index++, outer_class_info_index); + inner_classes->at_put(index++, inner_name_index); + inner_classes->at_put(index++, inner_access_flags.as_short()); + } + + // 4347400: make sure there's no duplicate entry in the classes array + if (_need_verify && _major_version >= JAVA_1_5_VERSION) { + for(int i = 0; i < length * 4; i += 4) { + for(int j = i + 4; j < length * 4; j += 4) { + guarantee_property((inner_classes->at(i) != inner_classes->at(j) || + inner_classes->at(i+1) != inner_classes->at(j+1) || + inner_classes->at(i+2) != inner_classes->at(j+2) || + inner_classes->at(i+3) != inner_classes->at(j+3)), + "Duplicate entry in InnerClasses in class file %s", + CHECK_0); + } + } + } + + // Set EnclosingMethod class and method indexes. + if (parsed_enclosingmethod_attribute) { + inner_classes->at_put(index++, enclosing_method_class_index); + inner_classes->at_put(index++, enclosing_method_method_index); + } + assert(index == size, "wrong size"); + + // Restore buffer's current position. + cfs->set_current(current_mark); + + return length; +} + +void ClassFileParser::parse_classfile_synthetic_attribute(TRAPS) { + set_class_synthetic_flag(true); +} + +void ClassFileParser::parse_classfile_signature_attribute(TRAPS) { + ClassFileStream* cfs = stream(); + u2 signature_index = cfs->get_u2(CHECK); + check_property( + valid_symbol_at(signature_index), + "Invalid constant pool index %u in Signature attribute in class file %s", + signature_index, CHECK); + set_class_generic_signature_index(signature_index); +} + +void ClassFileParser::parse_classfile_bootstrap_methods_attribute(u4 attribute_byte_length, TRAPS) { + ClassFileStream* cfs = stream(); + u1* current_start = cfs->current(); + + guarantee_property(attribute_byte_length >= sizeof(u2), + "Invalid BootstrapMethods attribute length %u in class file %s", + attribute_byte_length, + CHECK); + + cfs->guarantee_more(attribute_byte_length, CHECK); + + int attribute_array_length = cfs->get_u2_fast(); + + guarantee_property(_max_bootstrap_specifier_index < attribute_array_length, + "Short length on BootstrapMethods in class file %s", + CHECK); + + + // The attribute contains a counted array of counted tuples of shorts, + // represending bootstrap specifiers: + // length*{bootstrap_method_index, argument_count*{argument_index}} + int operand_count = (attribute_byte_length - sizeof(u2)) / sizeof(u2); + // operand_count = number of shorts in attr, except for leading length + + // The attribute is copied into a short[] array. + // The array begins with a series of short[2] pairs, one for each tuple. + int index_size = (attribute_array_length * 2); + + Array* operands = MetadataFactory::new_array(_loader_data, index_size + operand_count, CHECK); + + // Eagerly assign operands so they will be deallocated with the constant + // pool if there is an error. + _cp->set_operands(operands); + + int operand_fill_index = index_size; + int cp_size = _cp->length(); + + for (int n = 0; n < attribute_array_length; n++) { + // Store a 32-bit offset into the header of the operand array. + ConstantPool::operand_offset_at_put(operands, n, operand_fill_index); + + // Read a bootstrap specifier. + cfs->guarantee_more(sizeof(u2) * 2, CHECK); // bsm, argc + u2 bootstrap_method_index = cfs->get_u2_fast(); + u2 argument_count = cfs->get_u2_fast(); + check_property( + valid_cp_range(bootstrap_method_index, cp_size) && + _cp->tag_at(bootstrap_method_index).is_method_handle(), + "bootstrap_method_index %u has bad constant type in class file %s", + bootstrap_method_index, + CHECK); + + guarantee_property((operand_fill_index + 1 + argument_count) < operands->length(), + "Invalid BootstrapMethods num_bootstrap_methods or num_bootstrap_arguments value in class file %s", + CHECK); + + operands->at_put(operand_fill_index++, bootstrap_method_index); + operands->at_put(operand_fill_index++, argument_count); + + cfs->guarantee_more(sizeof(u2) * argument_count, CHECK); // argv[argc] + for (int j = 0; j < argument_count; j++) { + u2 argument_index = cfs->get_u2_fast(); + check_property( + valid_cp_range(argument_index, cp_size) && + _cp->tag_at(argument_index).is_loadable_constant(), + "argument_index %u has bad constant type in class file %s", + argument_index, + CHECK); + operands->at_put(operand_fill_index++, argument_index); + } + } + + u1* current_end = cfs->current(); + guarantee_property(current_end == current_start + attribute_byte_length, + "Bad length on BootstrapMethods in class file %s", + CHECK); +} + +void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotationCollector* parsed_annotations, + TRAPS) { + ClassFileStream* cfs = stream(); + // Set inner classes attribute to default sentinel + _inner_classes = Universe::the_empty_short_array(); + cfs->guarantee_more(2, CHECK); // attributes_count + u2 attributes_count = cfs->get_u2_fast(); + bool parsed_sourcefile_attribute = false; + bool parsed_innerclasses_attribute = false; + bool parsed_enclosingmethod_attribute = false; + bool parsed_bootstrap_methods_attribute = false; + u1* runtime_visible_annotations = NULL; + int runtime_visible_annotations_length = 0; + u1* runtime_invisible_annotations = NULL; + int runtime_invisible_annotations_length = 0; + u1* runtime_visible_type_annotations = NULL; + int runtime_visible_type_annotations_length = 0; + u1* runtime_invisible_type_annotations = NULL; + int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_type_annotations_exists = false; + bool runtime_invisible_annotations_exists = false; + bool parsed_source_debug_ext_annotations_exist = false; + u1* inner_classes_attribute_start = NULL; + u4 inner_classes_attribute_length = 0; + u2 enclosing_method_class_index = 0; + u2 enclosing_method_method_index = 0; + // Iterate over attributes + while (attributes_count--) { + cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length + u2 attribute_name_index = cfs->get_u2_fast(); + u4 attribute_length = cfs->get_u4_fast(); + check_property( + valid_symbol_at(attribute_name_index), + "Attribute name has bad constant pool index %u in class file %s", + attribute_name_index, CHECK); + Symbol* tag = _cp->symbol_at(attribute_name_index); + if (tag == vmSymbols::tag_source_file()) { + // Check for SourceFile tag + if (_need_verify) { + guarantee_property(attribute_length == 2, "Wrong SourceFile attribute length in class file %s", CHECK); + } + if (parsed_sourcefile_attribute) { + classfile_parse_error("Multiple SourceFile attributes in class file %s", CHECK); + } else { + parsed_sourcefile_attribute = true; + } + parse_classfile_sourcefile_attribute(CHECK); + } else if (tag == vmSymbols::tag_source_debug_extension()) { + // Check for SourceDebugExtension tag + if (parsed_source_debug_ext_annotations_exist) { + classfile_parse_error( + "Multiple SourceDebugExtension attributes in class file %s", CHECK); + } + parsed_source_debug_ext_annotations_exist = true; + parse_classfile_source_debug_extension_attribute((int)attribute_length, CHECK); + } else if (tag == vmSymbols::tag_inner_classes()) { + // Check for InnerClasses tag + if (parsed_innerclasses_attribute) { + classfile_parse_error("Multiple InnerClasses attributes in class file %s", CHECK); + } else { + parsed_innerclasses_attribute = true; + } + inner_classes_attribute_start = cfs->get_u1_buffer(); + inner_classes_attribute_length = attribute_length; + cfs->skip_u1(inner_classes_attribute_length, CHECK); + } else if (tag == vmSymbols::tag_synthetic()) { + // Check for Synthetic tag + // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec + if (attribute_length != 0) { + classfile_parse_error( + "Invalid Synthetic classfile attribute length %u in class file %s", + attribute_length, CHECK); + } + parse_classfile_synthetic_attribute(CHECK); + } else if (tag == vmSymbols::tag_deprecated()) { + // Check for Deprecatd tag - 4276120 + if (attribute_length != 0) { + classfile_parse_error( + "Invalid Deprecated classfile attribute length %u in class file %s", + attribute_length, CHECK); + } + } else if (_major_version >= JAVA_1_5_VERSION) { + if (tag == vmSymbols::tag_signature()) { + if (attribute_length != 2) { + classfile_parse_error( + "Wrong Signature attribute length %u in class file %s", + attribute_length, CHECK); + } + parse_classfile_signature_attribute(CHECK); + } else if (tag == vmSymbols::tag_runtime_visible_annotations()) { + if (runtime_visible_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleAnnotations attributes in class file %s", CHECK); + } + runtime_visible_annotations_length = attribute_length; + runtime_visible_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_annotations != NULL, "null visible annotations"); + parse_annotations(runtime_visible_annotations, + runtime_visible_annotations_length, + parsed_annotations, + CHECK); + cfs->skip_u1(runtime_visible_annotations_length, CHECK); + } else if (tag == vmSymbols::tag_runtime_invisible_annotations()) { + if (runtime_invisible_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleAnnotations attributes in class file %s", CHECK); + } + runtime_invisible_annotations_exists = true; + if (PreserveAllAnnotations) { + runtime_invisible_annotations_length = attribute_length; + runtime_invisible_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_annotations != NULL, "null invisible annotations"); + } + cfs->skip_u1(attribute_length, CHECK); + } else if (tag == vmSymbols::tag_enclosing_method()) { + if (parsed_enclosingmethod_attribute) { + classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK); + } else { + parsed_enclosingmethod_attribute = true; + } + guarantee_property(attribute_length == 4, + "Wrong EnclosingMethod attribute length %u in class file %s", + attribute_length, CHECK); + cfs->guarantee_more(4, CHECK); // class_index, method_index + enclosing_method_class_index = cfs->get_u2_fast(); + enclosing_method_method_index = cfs->get_u2_fast(); + if (enclosing_method_class_index == 0) { + classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK); + } + // Validate the constant pool indices and types + check_property(valid_klass_reference_at(enclosing_method_class_index), + "Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK); + if (enclosing_method_method_index != 0 && + (!_cp->is_within_bounds(enclosing_method_method_index) || + !_cp->tag_at(enclosing_method_method_index).is_name_and_type())) { + classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK); + } + } else if (tag == vmSymbols::tag_bootstrap_methods() && + _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { + if (parsed_bootstrap_methods_attribute) + classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK); + parsed_bootstrap_methods_attribute = true; + parse_classfile_bootstrap_methods_attribute(attribute_length, CHECK); + } else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) { + if (runtime_visible_type_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleTypeAnnotations attributes in class file %s", CHECK); + } + runtime_visible_type_annotations_length = attribute_length; + runtime_visible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); + // No need for the VM to parse Type annotations + cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); + } else if (tag == vmSymbols::tag_runtime_invisible_type_annotations()) { + if (runtime_invisible_type_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleTypeAnnotations attributes in class file %s", CHECK); + } else { + runtime_invisible_type_annotations_exists = true; + } + if (PreserveAllAnnotations) { + runtime_invisible_type_annotations_length = attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + } + cfs->skip_u1(attribute_length, CHECK); + } else { + // Unknown attribute + cfs->skip_u1(attribute_length, CHECK); + } + } else { + // Unknown attribute + cfs->skip_u1(attribute_length, CHECK); + } + } + _annotations = assemble_annotations(runtime_visible_annotations, + runtime_visible_annotations_length, + runtime_invisible_annotations, + runtime_invisible_annotations_length, + CHECK); + _type_annotations = assemble_annotations(runtime_visible_type_annotations, + runtime_visible_type_annotations_length, + runtime_invisible_type_annotations, + runtime_invisible_type_annotations_length, + CHECK); + + if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) { + u2 num_of_classes = parse_classfile_inner_classes_attribute( + inner_classes_attribute_start, + parsed_innerclasses_attribute, + enclosing_method_class_index, + enclosing_method_method_index, + CHECK); + if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) { + guarantee_property( + inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes, + "Wrong InnerClasses attribute length in class file %s", CHECK); + } + } + + if (_max_bootstrap_specifier_index >= 0) { + guarantee_property(parsed_bootstrap_methods_attribute, + "Missing BootstrapMethods attribute in class file %s", CHECK); + } +} + +void ClassFileParser::apply_parsed_class_attributes(instanceKlassHandle k) { + if (_synthetic_flag) + k->set_is_synthetic(); + if (_sourcefile_index != 0) { + k->set_source_file_name_index(_sourcefile_index); + } + if (_generic_signature_index != 0) { + k->set_generic_signature_index(_generic_signature_index); + } + if (_sde_buffer != NULL) { + k->set_source_debug_extension(_sde_buffer, _sde_length); + } +} + +// Transfer ownership of metadata allocated to the InstanceKlass. +void ClassFileParser::apply_parsed_class_metadata( + instanceKlassHandle this_klass, + int java_fields_count, TRAPS) { + // Assign annotations if needed + if (_annotations != NULL || _type_annotations != NULL || + _fields_annotations != NULL || _fields_type_annotations != NULL) { + Annotations* annotations = Annotations::allocate(_loader_data, CHECK); + annotations->set_class_annotations(_annotations); + annotations->set_class_type_annotations(_type_annotations); + annotations->set_fields_annotations(_fields_annotations); + annotations->set_fields_type_annotations(_fields_type_annotations); + this_klass->set_annotations(annotations); + } + + _cp->set_pool_holder(this_klass()); + this_klass->set_constants(_cp); + this_klass->set_fields(_fields, java_fields_count); + this_klass->set_methods(_methods); + this_klass->set_inner_classes(_inner_classes); + this_klass->set_local_interfaces(_local_interfaces); + this_klass->set_transitive_interfaces(_transitive_interfaces); + + // Clear out these fields so they don't get deallocated by the destructor + clear_class_metadata(); +} + +AnnotationArray* ClassFileParser::assemble_annotations(u1* runtime_visible_annotations, + int runtime_visible_annotations_length, + u1* runtime_invisible_annotations, + int runtime_invisible_annotations_length, TRAPS) { + AnnotationArray* annotations = NULL; + if (runtime_visible_annotations != NULL || + runtime_invisible_annotations != NULL) { + annotations = MetadataFactory::new_array(_loader_data, + runtime_visible_annotations_length + + runtime_invisible_annotations_length, + CHECK_(annotations)); + if (runtime_visible_annotations != NULL) { + for (int i = 0; i < runtime_visible_annotations_length; i++) { + annotations->at_put(i, runtime_visible_annotations[i]); + } + } + if (runtime_invisible_annotations != NULL) { + for (int i = 0; i < runtime_invisible_annotations_length; i++) { + int append = runtime_visible_annotations_length+i; + annotations->at_put(append, runtime_invisible_annotations[i]); + } + } + } + return annotations; +} + +instanceKlassHandle ClassFileParser::parse_super_class(int super_class_index, + TRAPS) { + instanceKlassHandle super_klass; + if (super_class_index == 0) { + check_property(_class_name == vmSymbols::java_lang_Object(), + "Invalid superclass index %u in class file %s", + super_class_index, + CHECK_NULL); + } else { + check_property(valid_klass_reference_at(super_class_index), + "Invalid superclass index %u in class file %s", + super_class_index, + CHECK_NULL); + // The class name should be legal because it is checked when parsing constant pool. + // However, make sure it is not an array type. + bool is_array = false; + if (_cp->tag_at(super_class_index).is_klass()) { + super_klass = instanceKlassHandle(THREAD, _cp->resolved_klass_at(super_class_index)); + if (_need_verify) + is_array = super_klass->oop_is_array(); + } else if (_need_verify) { + is_array = (_cp->klass_name_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY); + } + if (_need_verify) { + guarantee_property(!is_array, + "Bad superclass name in class file %s", CHECK_NULL); + } + } + return super_klass; +} + + +// Values needed for oopmap and InstanceKlass creation +class FieldLayoutInfo : public StackObj { + public: + int* nonstatic_oop_offsets; + unsigned int* nonstatic_oop_counts; + unsigned int nonstatic_oop_map_count; + unsigned int total_oop_map_count; + int instance_size; + int nonstatic_field_size; + int static_field_size; + bool has_nonstatic_fields; +}; + +// Layout fields and fill in FieldLayoutInfo. Could use more refactoring! +void ClassFileParser::layout_fields(Handle class_loader, + FieldAllocationCount* fac, + ClassAnnotationCollector* parsed_annotations, + FieldLayoutInfo* info, + TRAPS) { + + // Field size and offset computation + int nonstatic_field_size = _super_klass() == NULL ? 0 : _super_klass()->nonstatic_field_size(); + int next_static_oop_offset; + int next_static_double_offset; + int next_static_word_offset; + int next_static_short_offset; + int next_static_byte_offset; + int next_nonstatic_oop_offset; + int next_nonstatic_double_offset; + int next_nonstatic_word_offset; + int next_nonstatic_short_offset; + int next_nonstatic_byte_offset; + int first_nonstatic_oop_offset; + int next_nonstatic_field_offset; + int next_nonstatic_padded_offset; + + // Count the contended fields by type. + // + // We ignore static fields, because @Contended is not supported for them. + // The layout code below will also ignore the static fields. + int nonstatic_contended_count = 0; + FieldAllocationCount fac_contended; + for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { + FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); + if (fs.is_contended()) { + fac_contended.count[atype]++; + if (!fs.access_flags().is_static()) { + nonstatic_contended_count++; + } + } + } + + + // Calculate the starting byte offsets + next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields(); + next_static_double_offset = next_static_oop_offset + + ((fac->count[STATIC_OOP]) * heapOopSize); + if ( fac->count[STATIC_DOUBLE] && + (Universe::field_type_should_be_aligned(T_DOUBLE) || + Universe::field_type_should_be_aligned(T_LONG)) ) { + next_static_double_offset = align_size_up(next_static_double_offset, BytesPerLong); + } + + next_static_word_offset = next_static_double_offset + + ((fac->count[STATIC_DOUBLE]) * BytesPerLong); + next_static_short_offset = next_static_word_offset + + ((fac->count[STATIC_WORD]) * BytesPerInt); + next_static_byte_offset = next_static_short_offset + + ((fac->count[STATIC_SHORT]) * BytesPerShort); + + int nonstatic_fields_start = instanceOopDesc::base_offset_in_bytes() + + nonstatic_field_size * heapOopSize; + + next_nonstatic_field_offset = nonstatic_fields_start; + + bool is_contended_class = parsed_annotations->is_contended(); + + // Class is contended, pad before all the fields + if (is_contended_class) { + next_nonstatic_field_offset += ContendedPaddingWidth; + } + + // Compute the non-contended fields count. + // The packing code below relies on these counts to determine if some field + // can be squeezed into the alignment gap. Contended fields are obviously + // exempt from that. + unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE]; + unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD]; + unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT]; + unsigned int nonstatic_byte_count = fac->count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE]; + unsigned int nonstatic_oop_count = fac->count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP]; + + // Total non-static fields count, including every contended field + unsigned int nonstatic_fields_count = fac->count[NONSTATIC_DOUBLE] + fac->count[NONSTATIC_WORD] + + fac->count[NONSTATIC_SHORT] + fac->count[NONSTATIC_BYTE] + + fac->count[NONSTATIC_OOP]; + + bool super_has_nonstatic_fields = + (_super_klass() != NULL && _super_klass->has_nonstatic_fields()); + bool has_nonstatic_fields = super_has_nonstatic_fields || (nonstatic_fields_count != 0); + + + // Prepare list of oops for oop map generation. + // + // "offset" and "count" lists are describing the set of contiguous oop + // regions. offset[i] is the start of the i-th region, which then has + // count[i] oops following. Before we know how many regions are required, + // we pessimistically allocate the maps to fit all the oops into the + // distinct regions. + // + // TODO: We add +1 to always allocate non-zero resource arrays; we need + // to figure out if we still need to do this. + int* nonstatic_oop_offsets; + unsigned int* nonstatic_oop_counts; + unsigned int nonstatic_oop_map_count = 0; + unsigned int max_nonstatic_oop_maps = fac->count[NONSTATIC_OOP] + 1; + + nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, int, max_nonstatic_oop_maps); + nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD( + THREAD, unsigned int, max_nonstatic_oop_maps); + + first_nonstatic_oop_offset = 0; // will be set for first oop field + + bool compact_fields = CompactFields; + int allocation_style = FieldsAllocationStyle; + if( allocation_style < 0 || allocation_style > 2 ) { // Out of range? + assert(false, "0 <= FieldsAllocationStyle <= 2"); + allocation_style = 1; // Optimistic + } + + // The next classes have predefined hard-coded fields offsets + // (see in JavaClasses::compute_hard_coded_offsets()). + // Use default fields allocation order for them. + if( (allocation_style != 0 || compact_fields ) && class_loader.is_null() && + (_class_name == vmSymbols::java_lang_AssertionStatusDirectives() || + _class_name == vmSymbols::java_lang_Class() || + _class_name == vmSymbols::java_lang_ClassLoader() || + _class_name == vmSymbols::java_lang_ref_Reference() || + _class_name == vmSymbols::java_lang_ref_SoftReference() || + _class_name == vmSymbols::java_lang_StackTraceElement() || + _class_name == vmSymbols::java_lang_String() || + _class_name == vmSymbols::java_lang_Throwable() || + _class_name == vmSymbols::java_lang_Boolean() || + _class_name == vmSymbols::java_lang_Character() || + _class_name == vmSymbols::java_lang_Float() || + _class_name == vmSymbols::java_lang_Double() || + _class_name == vmSymbols::java_lang_Byte() || + _class_name == vmSymbols::java_lang_Short() || + _class_name == vmSymbols::java_lang_Integer() || + _class_name == vmSymbols::java_lang_Long())) { + allocation_style = 0; // Allocate oops first + compact_fields = false; // Don't compact fields + } + + // Rearrange fields for a given allocation style + if( allocation_style == 0 ) { + // Fields order: oops, longs/doubles, ints, shorts/chars, bytes, padded fields + next_nonstatic_oop_offset = next_nonstatic_field_offset; + next_nonstatic_double_offset = next_nonstatic_oop_offset + + (nonstatic_oop_count * heapOopSize); + } else if( allocation_style == 1 ) { + // Fields order: longs/doubles, ints, shorts/chars, bytes, oops, padded fields + next_nonstatic_double_offset = next_nonstatic_field_offset; + } else if( allocation_style == 2 ) { + // Fields allocation: oops fields in super and sub classes are together. + if( nonstatic_field_size > 0 && _super_klass() != NULL && + _super_klass->nonstatic_oop_map_size() > 0 ) { + unsigned int map_count = _super_klass->nonstatic_oop_map_count(); + OopMapBlock* first_map = _super_klass->start_of_nonstatic_oop_maps(); + OopMapBlock* last_map = first_map + map_count - 1; + int next_offset = last_map->offset() + (last_map->count() * heapOopSize); + if (next_offset == next_nonstatic_field_offset) { + allocation_style = 0; // allocate oops first + next_nonstatic_oop_offset = next_nonstatic_field_offset; + next_nonstatic_double_offset = next_nonstatic_oop_offset + + (nonstatic_oop_count * heapOopSize); + } + } + if( allocation_style == 2 ) { + allocation_style = 1; // allocate oops last + next_nonstatic_double_offset = next_nonstatic_field_offset; + } + } else { + ShouldNotReachHere(); + } + + int nonstatic_oop_space_count = 0; + int nonstatic_word_space_count = 0; + int nonstatic_short_space_count = 0; + int nonstatic_byte_space_count = 0; + int nonstatic_oop_space_offset; + int nonstatic_word_space_offset; + int nonstatic_short_space_offset; + int nonstatic_byte_space_offset; + + // Try to squeeze some of the fields into the gaps due to + // long/double alignment. + if( nonstatic_double_count > 0 ) { + int offset = next_nonstatic_double_offset; + next_nonstatic_double_offset = align_size_up(offset, BytesPerLong); + if( compact_fields && offset != next_nonstatic_double_offset ) { + // Allocate available fields into the gap before double field. + int length = next_nonstatic_double_offset - offset; + assert(length == BytesPerInt, ""); + nonstatic_word_space_offset = offset; + if( nonstatic_word_count > 0 ) { + nonstatic_word_count -= 1; + nonstatic_word_space_count = 1; // Only one will fit + length -= BytesPerInt; + offset += BytesPerInt; + } + nonstatic_short_space_offset = offset; + while( length >= BytesPerShort && nonstatic_short_count > 0 ) { + nonstatic_short_count -= 1; + nonstatic_short_space_count += 1; + length -= BytesPerShort; + offset += BytesPerShort; + } + nonstatic_byte_space_offset = offset; + while( length > 0 && nonstatic_byte_count > 0 ) { + nonstatic_byte_count -= 1; + nonstatic_byte_space_count += 1; + length -= 1; + } + // Allocate oop field in the gap if there are no other fields for that. + nonstatic_oop_space_offset = offset; + if( length >= heapOopSize && nonstatic_oop_count > 0 && + allocation_style != 0 ) { // when oop fields not first + nonstatic_oop_count -= 1; + nonstatic_oop_space_count = 1; // Only one will fit + length -= heapOopSize; + offset += heapOopSize; + } + } + } + + next_nonstatic_word_offset = next_nonstatic_double_offset + + (nonstatic_double_count * BytesPerLong); + next_nonstatic_short_offset = next_nonstatic_word_offset + + (nonstatic_word_count * BytesPerInt); + next_nonstatic_byte_offset = next_nonstatic_short_offset + + (nonstatic_short_count * BytesPerShort); + next_nonstatic_padded_offset = next_nonstatic_byte_offset + + nonstatic_byte_count; + + // let oops jump before padding with this allocation style + if( allocation_style == 1 ) { + next_nonstatic_oop_offset = next_nonstatic_padded_offset; + if( nonstatic_oop_count > 0 ) { + next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize); + } + next_nonstatic_padded_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize); + } + + // Iterate over fields again and compute correct offsets. + // The field allocation type was temporarily stored in the offset slot. + // oop fields are located before non-oop fields (static and non-static). + for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { + + // skip already laid out fields + if (fs.is_offset_set()) continue; + + // contended instance fields are handled below + if (fs.is_contended() && !fs.access_flags().is_static()) continue; + + int real_offset; + FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); + + // pack the rest of the fields + switch (atype) { + case STATIC_OOP: + real_offset = next_static_oop_offset; + next_static_oop_offset += heapOopSize; + break; + case STATIC_BYTE: + real_offset = next_static_byte_offset; + next_static_byte_offset += 1; + break; + case STATIC_SHORT: + real_offset = next_static_short_offset; + next_static_short_offset += BytesPerShort; + break; + case STATIC_WORD: + real_offset = next_static_word_offset; + next_static_word_offset += BytesPerInt; + break; + case STATIC_DOUBLE: + real_offset = next_static_double_offset; + next_static_double_offset += BytesPerLong; + break; + case NONSTATIC_OOP: + if( nonstatic_oop_space_count > 0 ) { + real_offset = nonstatic_oop_space_offset; + nonstatic_oop_space_offset += heapOopSize; + nonstatic_oop_space_count -= 1; + } else { + real_offset = next_nonstatic_oop_offset; + next_nonstatic_oop_offset += heapOopSize; + } + // Update oop maps + if( nonstatic_oop_map_count > 0 && + nonstatic_oop_offsets[nonstatic_oop_map_count - 1] == + real_offset - + int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) * + heapOopSize ) { + // Extend current oop map + assert(nonstatic_oop_map_count - 1 < max_nonstatic_oop_maps, "range check"); + nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1; + } else { + // Create new oop map + assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check"); + nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset; + nonstatic_oop_counts [nonstatic_oop_map_count] = 1; + nonstatic_oop_map_count += 1; + if( first_nonstatic_oop_offset == 0 ) { // Undefined + first_nonstatic_oop_offset = real_offset; + } + } + break; + case NONSTATIC_BYTE: + if( nonstatic_byte_space_count > 0 ) { + real_offset = nonstatic_byte_space_offset; + nonstatic_byte_space_offset += 1; + nonstatic_byte_space_count -= 1; + } else { + real_offset = next_nonstatic_byte_offset; + next_nonstatic_byte_offset += 1; + } + break; + case NONSTATIC_SHORT: + if( nonstatic_short_space_count > 0 ) { + real_offset = nonstatic_short_space_offset; + nonstatic_short_space_offset += BytesPerShort; + nonstatic_short_space_count -= 1; + } else { + real_offset = next_nonstatic_short_offset; + next_nonstatic_short_offset += BytesPerShort; + } + break; + case NONSTATIC_WORD: + if( nonstatic_word_space_count > 0 ) { + real_offset = nonstatic_word_space_offset; + nonstatic_word_space_offset += BytesPerInt; + nonstatic_word_space_count -= 1; + } else { + real_offset = next_nonstatic_word_offset; + next_nonstatic_word_offset += BytesPerInt; + } + break; + case NONSTATIC_DOUBLE: + real_offset = next_nonstatic_double_offset; + next_nonstatic_double_offset += BytesPerLong; + break; + default: + ShouldNotReachHere(); + } + fs.set_offset(real_offset); + } + + + // Handle the contended cases. + // + // Each contended field should not intersect the cache line with another contended field. + // In the absence of alignment information, we end up with pessimistically separating + // the fields with full-width padding. + // + // Additionally, this should not break alignment for the fields, so we round the alignment up + // for each field. + if (nonstatic_contended_count > 0) { + + // if there is at least one contended field, we need to have pre-padding for them + next_nonstatic_padded_offset += ContendedPaddingWidth; + + // collect all contended groups + BitMap bm(_cp->size()); + for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { + // skip already laid out fields + if (fs.is_offset_set()) continue; + + if (fs.is_contended()) { + bm.set_bit(fs.contended_group()); + } + } + + int current_group = -1; + while ((current_group = (int)bm.get_next_one_offset(current_group + 1)) != (int)bm.size()) { + + for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { + + // skip already laid out fields + if (fs.is_offset_set()) continue; + + // skip non-contended fields and fields from different group + if (!fs.is_contended() || (fs.contended_group() != current_group)) continue; + + // handle statics below + if (fs.access_flags().is_static()) continue; + + int real_offset; + FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); + + switch (atype) { + case NONSTATIC_BYTE: + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, 1); + real_offset = next_nonstatic_padded_offset; + next_nonstatic_padded_offset += 1; + break; + + case NONSTATIC_SHORT: + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerShort); + real_offset = next_nonstatic_padded_offset; + next_nonstatic_padded_offset += BytesPerShort; + break; + + case NONSTATIC_WORD: + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerInt); + real_offset = next_nonstatic_padded_offset; + next_nonstatic_padded_offset += BytesPerInt; + break; + + case NONSTATIC_DOUBLE: + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerLong); + real_offset = next_nonstatic_padded_offset; + next_nonstatic_padded_offset += BytesPerLong; + break; + + case NONSTATIC_OOP: + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, heapOopSize); + real_offset = next_nonstatic_padded_offset; + next_nonstatic_padded_offset += heapOopSize; + + // Create new oop map + assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check"); + nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset; + nonstatic_oop_counts [nonstatic_oop_map_count] = 1; + nonstatic_oop_map_count += 1; + if( first_nonstatic_oop_offset == 0 ) { // Undefined + first_nonstatic_oop_offset = real_offset; + } + break; + + default: + ShouldNotReachHere(); + } + + if (fs.contended_group() == 0) { + // Contended group defines the equivalence class over the fields: + // the fields within the same contended group are not inter-padded. + // The only exception is default group, which does not incur the + // equivalence, and so requires intra-padding. + next_nonstatic_padded_offset += ContendedPaddingWidth; + } + + fs.set_offset(real_offset); + } // for + + // Start laying out the next group. + // Note that this will effectively pad the last group in the back; + // this is expected to alleviate memory contention effects for + // subclass fields and/or adjacent object. + // If this was the default group, the padding is already in place. + if (current_group != 0) { + next_nonstatic_padded_offset += ContendedPaddingWidth; + } + } + + // handle static fields + } + + // Entire class is contended, pad in the back. + // This helps to alleviate memory contention effects for subclass fields + // and/or adjacent object. + if (is_contended_class) { + next_nonstatic_padded_offset += ContendedPaddingWidth; + } + + int notaligned_nonstatic_fields_end = next_nonstatic_padded_offset; + + int nonstatic_fields_end = align_size_up(notaligned_nonstatic_fields_end, heapOopSize); + int instance_end = align_size_up(notaligned_nonstatic_fields_end, wordSize); + int static_fields_end = align_size_up(next_static_byte_offset, wordSize); + + int static_field_size = (static_fields_end - + InstanceMirrorKlass::offset_of_static_fields()) / wordSize; + nonstatic_field_size = nonstatic_field_size + + (nonstatic_fields_end - nonstatic_fields_start) / heapOopSize; + + int instance_size = align_object_size(instance_end / wordSize); + + assert(instance_size == align_object_size(align_size_up( + (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), + wordSize) / wordSize), "consistent layout helper value"); + + // Invariant: nonstatic_field end/start should only change if there are + // nonstatic fields in the class, or if the class is contended. We compare + // against the non-aligned value, so that end alignment will not fail the + // assert without actually having the fields. + assert((notaligned_nonstatic_fields_end == nonstatic_fields_start) || + is_contended_class || + (nonstatic_fields_count > 0), "double-check nonstatic start/end"); + + // Number of non-static oop map blocks allocated at end of klass. + const unsigned int total_oop_map_count = + compute_oop_map_count(_super_klass, nonstatic_oop_map_count, + first_nonstatic_oop_offset); + +#ifndef PRODUCT + if (PrintFieldLayout) { + print_field_layout(_class_name, + _fields, + _cp, + instance_size, + nonstatic_fields_start, + nonstatic_fields_end, + static_fields_end); + } + +#endif + // Pass back information needed for InstanceKlass creation + info->nonstatic_oop_offsets = nonstatic_oop_offsets; + info->nonstatic_oop_counts = nonstatic_oop_counts; + info->nonstatic_oop_map_count = nonstatic_oop_map_count; + info->total_oop_map_count = total_oop_map_count; + info->instance_size = instance_size; + info->static_field_size = static_field_size; + info->nonstatic_field_size = nonstatic_field_size; + info->has_nonstatic_fields = has_nonstatic_fields; +} + + +instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, + ClassLoaderData* loader_data, + Handle protection_domain, + KlassHandle host_klass, + GrowableArray* cp_patches, + TempNewSymbol& parsed_name, + bool verify, + TRAPS) { + + // When a retransformable agent is attached, JVMTI caches the + // class bytes that existed before the first retransformation. + // If RedefineClasses() was used before the retransformable + // agent attached, then the cached class bytes may not be the + // original class bytes. + JvmtiCachedClassFileData *cached_class_file = NULL; + Handle class_loader(THREAD, loader_data->class_loader()); + bool has_default_methods = false; + ResourceMark rm(THREAD); + + ClassFileStream* cfs = stream(); + // Timing + assert(THREAD->is_Java_thread(), "must be a JavaThread"); + JavaThread* jt = (JavaThread*) THREAD; + + PerfClassTraceTime ctimer(ClassLoader::perf_class_parse_time(), + ClassLoader::perf_class_parse_selftime(), + NULL, + jt->get_thread_stat()->perf_recursion_counts_addr(), + jt->get_thread_stat()->perf_timers_addr(), + PerfClassTraceTime::PARSE_CLASS); + + init_parsed_class_attributes(loader_data); + + if (JvmtiExport::should_post_class_file_load_hook()) { + // Get the cached class file bytes (if any) from the class that + // is being redefined or retransformed. We use jvmti_thread_state() + // instead of JvmtiThreadState::state_for(jt) so we don't allocate + // a JvmtiThreadState any earlier than necessary. This will help + // avoid the bug described by 7126851. + JvmtiThreadState *state = jt->jvmti_thread_state(); + if (state != NULL) { + KlassHandle *h_class_being_redefined = + state->get_class_being_redefined(); + if (h_class_being_redefined != NULL) { + instanceKlassHandle ikh_class_being_redefined = + instanceKlassHandle(THREAD, (*h_class_being_redefined)()); + cached_class_file = ikh_class_being_redefined->get_cached_class_file(); + } + } + + unsigned char* ptr = cfs->buffer(); + unsigned char* end_ptr = cfs->buffer() + cfs->length(); + + JvmtiExport::post_class_file_load_hook(name, class_loader(), protection_domain, + &ptr, &end_ptr, &cached_class_file); + + if (ptr != cfs->buffer()) { + // JVMTI agent has modified class file data. + // Set new class file stream using JVMTI agent modified + // class file data. + cfs = new ClassFileStream(ptr, end_ptr - ptr, cfs->source()); + set_stream(cfs); + } + } + + _host_klass = host_klass; + _cp_patches = cp_patches; + + instanceKlassHandle nullHandle; + + // Figure out whether we can skip format checking (matching classic VM behavior) + if (DumpSharedSpaces) { + // verify == true means it's a 'remote' class (i.e., non-boot class) + // Verification decision is based on BytecodeVerificationRemote flag + // for those classes. + _need_verify = (verify) ? BytecodeVerificationRemote : + BytecodeVerificationLocal; + } else { + _need_verify = Verifier::should_verify_for(class_loader(), verify); + } + + // Set the verify flag in stream + cfs->set_verify(_need_verify); + + // Save the class file name for easier error message printing. + _class_name = (name != NULL) ? name : vmSymbols::unknown_class_name(); + + cfs->guarantee_more(8, CHECK_(nullHandle)); // magic, major, minor + // Magic value + u4 magic = cfs->get_u4_fast(); + guarantee_property(magic == JAVA_CLASSFILE_MAGIC, + "Incompatible magic value %u in class file %s", + magic, CHECK_(nullHandle)); + + // Version numbers + u2 minor_version = cfs->get_u2_fast(); + u2 major_version = cfs->get_u2_fast(); + + if (DumpSharedSpaces && major_version < JAVA_1_5_VERSION) { + ResourceMark rm; + warning("Pre JDK 1.5 class not supported by CDS: %u.%u %s", + major_version, minor_version, name->as_C_string()); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_UnsupportedClassVersionError(), + "Unsupported major.minor version for dump time %u.%u", + major_version, + minor_version); + } + + // Check version numbers - we check this even with verifier off + if (!is_supported_version(major_version, minor_version)) { + if (name == NULL) { + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_UnsupportedClassVersionError(), + "Unsupported class file version %u.%u, " + "this version of the Java Runtime only recognizes class file versions up to %u.%u", + major_version, + minor_version, + JAVA_MAX_SUPPORTED_VERSION, + JAVA_MAX_SUPPORTED_MINOR_VERSION); + } else { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_UnsupportedClassVersionError(), + "%s has been compiled by a more recent version of the Java Runtime (class file version %u.%u), " + "this version of the Java Runtime only recognizes class file versions up to %u.%u", + name->as_C_string(), + major_version, + minor_version, + JAVA_MAX_SUPPORTED_VERSION, + JAVA_MAX_SUPPORTED_MINOR_VERSION); + } + return nullHandle; + } + + _major_version = major_version; + _minor_version = minor_version; + + + // Check if verification needs to be relaxed for this class file + // Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376) + _relax_verify = Verifier::relax_verify_for(class_loader()); + + // Constant pool + constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle)); + + int cp_size = cp->length(); + + cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len + + // Access flags + AccessFlags access_flags; + jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_CLASS_MODIFIERS; + + if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) { + // Set abstract bit for old class files for backward compatibility + flags |= JVM_ACC_ABSTRACT; + } + verify_legal_class_modifiers(flags, CHECK_(nullHandle)); + access_flags.set_flags(flags); + + // This class and superclass + u2 this_class_index = cfs->get_u2_fast(); + check_property( + valid_cp_range(this_class_index, cp_size) && + cp->tag_at(this_class_index).is_unresolved_klass(), + "Invalid this class index %u in constant pool in class file %s", + this_class_index, CHECK_(nullHandle)); + + Symbol* class_name = cp->klass_name_at(this_class_index); + assert(class_name != NULL, "class_name can't be null"); + + // It's important to set parsed_name *before* resolving the super class. + // (it's used for cleanup by the caller if parsing fails) + parsed_name = class_name; + // parsed_name is returned and can be used if there's an error, so add to + // its reference count. Caller will decrement the refcount. + parsed_name->increment_refcount(); + + // Update _class_name which could be null previously to be class_name + _class_name = class_name; + + // Don't need to check whether this class name is legal or not. + // It has been checked when constant pool is parsed. + // However, make sure it is not an array type. + if (_need_verify) { + guarantee_property(class_name->byte_at(0) != JVM_SIGNATURE_ARRAY, + "Bad class name in class file %s", + CHECK_(nullHandle)); + } + + Klass* preserve_this_klass; // for storing result across HandleMark + + // release all handles when parsing is done + { HandleMark hm(THREAD); + + // Checks if name in class file matches requested name + if (name != NULL && class_name != name) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_NoClassDefFoundError(), + "%s (wrong name: %s)", + name->as_C_string(), + class_name->as_C_string() + ); + return nullHandle; + } + + if (TraceClassLoadingPreorder) { + tty->print("[Loading %s", (name != NULL) ? name->as_klass_external_name() : "NoName"); + if (cfs->source() != NULL) tty->print(" from %s", cfs->source()); + tty->print_cr("]"); + } +#if INCLUDE_CDS + if (DumpLoadedClassList != NULL && cfs->source() != NULL && classlist_file->is_open()) { + // Only dump the classes that can be stored into CDS archive + if (SystemDictionaryShared::is_sharing_possible(loader_data)) { + if (name != NULL) { + ResourceMark rm(THREAD); + classlist_file->print_cr("%s", name->as_C_string()); + classlist_file->flush(); + } + } + } +#endif + + u2 super_class_index = cfs->get_u2_fast(); + instanceKlassHandle super_klass = parse_super_class(super_class_index, + CHECK_NULL); + + // Interfaces + u2 itfs_len = cfs->get_u2_fast(); + Array* local_interfaces = + parse_interfaces(itfs_len, protection_domain, _class_name, + &has_default_methods, CHECK_(nullHandle)); + + u2 java_fields_count = 0; + // Fields (offsets are filled in later) + FieldAllocationCount fac; + Array* fields = parse_fields(class_name, + access_flags.is_interface(), + &fac, &java_fields_count, + CHECK_(nullHandle)); + // Methods + bool has_final_method = false; + AccessFlags promoted_flags; + promoted_flags.set_flags(0); + Array* methods = parse_methods(access_flags.is_interface(), + &promoted_flags, + &has_final_method, + &has_default_methods, + CHECK_(nullHandle)); + + // Additional attributes + ClassAnnotationCollector parsed_annotations; + parse_classfile_attributes(&parsed_annotations, CHECK_(nullHandle)); + + // Make sure this is the end of class file stream + guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle)); + + // We check super class after class file is parsed and format is checked + if (super_class_index > 0 && super_klass.is_null()) { + Symbol* sk = cp->klass_name_at(super_class_index); + if (access_flags.is_interface()) { + // Before attempting to resolve the superclass, check for class format + // errors not checked yet. + guarantee_property(sk == vmSymbols::java_lang_Object(), + "Interfaces must have java.lang.Object as superclass in class file %s", + CHECK_(nullHandle)); + } + Klass* k = SystemDictionary::resolve_super_or_fail(class_name, sk, + class_loader, + protection_domain, + true, + CHECK_(nullHandle)); + + KlassHandle kh (THREAD, k); + super_klass = instanceKlassHandle(THREAD, kh()); + } + if (super_klass.not_null()) { + + if (super_klass->has_default_methods()) { + has_default_methods = true; + } + + if (super_klass->is_interface()) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_IncompatibleClassChangeError(), + "class %s has interface %s as super class", + class_name->as_klass_external_name(), + super_klass->external_name() + ); + return nullHandle; + } + // Make sure super class is not final + if (super_klass->is_final()) { + THROW_MSG_(vmSymbols::java_lang_VerifyError(), "Cannot inherit from final class", nullHandle); + } + } + + // save super klass for error handling. + _super_klass = super_klass; + + // Compute the transitive list of all unique interfaces implemented by this class + _transitive_interfaces = + compute_transitive_interfaces(super_klass, local_interfaces, CHECK_(nullHandle)); + + // sort methods + intArray* method_ordering = sort_methods(methods); + + // promote flags from parse_methods() to the klass' flags + access_flags.add_promoted_flags(promoted_flags.as_int()); + + // Size of Java vtable (in words) + int vtable_size = 0; + int itable_size = 0; + int num_miranda_methods = 0; + + GrowableArray all_mirandas(20); + + klassVtable::compute_vtable_size_and_num_mirandas( + &vtable_size, &num_miranda_methods, &all_mirandas, super_klass(), methods, + access_flags, class_loader, class_name, local_interfaces, + CHECK_(nullHandle)); + + // Size of Java itable (in words) + itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(_transitive_interfaces); + + FieldLayoutInfo info; + layout_fields(class_loader, &fac, &parsed_annotations, &info, CHECK_NULL); + + int total_oop_map_size2 = + InstanceKlass::nonstatic_oop_map_size(info.total_oop_map_count); + + // Compute reference type + ReferenceType rt; + if (super_klass() == NULL) { + rt = REF_NONE; + } else { + rt = super_klass->reference_type(); + } + + // We can now create the basic Klass* for this klass + _klass = InstanceKlass::allocate_instance_klass(loader_data, + vtable_size, + itable_size, + info.static_field_size, + total_oop_map_size2, + rt, + access_flags, + name, + super_klass(), + !host_klass.is_null(), + CHECK_(nullHandle)); + instanceKlassHandle this_klass (THREAD, _klass); + + assert(this_klass->static_field_size() == info.static_field_size, "sanity"); + assert(this_klass->nonstatic_oop_map_count() == info.total_oop_map_count, + "sanity"); + + // Fill in information already parsed + this_klass->set_should_verify_class(verify); + jint lh = Klass::instance_layout_helper(info.instance_size, false); + this_klass->set_layout_helper(lh); + assert(this_klass->oop_is_instance(), "layout is correct"); + assert(this_klass->size_helper() == info.instance_size, "correct size_helper"); + // Not yet: supers are done below to support the new subtype-checking fields + //this_klass->set_super(super_klass()); + this_klass->set_class_loader_data(loader_data); + this_klass->set_nonstatic_field_size(info.nonstatic_field_size); + this_klass->set_has_nonstatic_fields(info.has_nonstatic_fields); + this_klass->set_static_oop_field_count(fac.count[STATIC_OOP]); + + apply_parsed_class_metadata(this_klass, java_fields_count, CHECK_NULL); + + if (has_final_method) { + this_klass->set_has_final_method(); + } + this_klass->copy_method_ordering(method_ordering, CHECK_NULL); + // The InstanceKlass::_methods_jmethod_ids cache + // is managed on the assumption that the initial cache + // size is equal to the number of methods in the class. If + // that changes, then InstanceKlass::idnum_can_increment() + // has to be changed accordingly. + this_klass->set_initial_method_idnum(methods->length()); + this_klass->set_name(cp->klass_name_at(this_class_index)); + if (is_anonymous()) // I am well known to myself + cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve + + this_klass->set_minor_version(minor_version); + this_klass->set_major_version(major_version); + this_klass->set_has_default_methods(has_default_methods); + + if (!host_klass.is_null()) { + assert (this_klass->is_anonymous(), "should be the same"); + this_klass->set_host_klass(host_klass()); + } + + // Set up Method*::intrinsic_id as soon as we know the names of methods. + // (We used to do this lazily, but now we query it in Rewriter, + // which is eagerly done for every method, so we might as well do it now, + // when everything is fresh in memory.) + if (Method::klass_id_for_intrinsics(this_klass()) != vmSymbols::NO_SID) { + for (int j = 0; j < methods->length(); j++) { + methods->at(j)->init_intrinsic_id(); + } + } + + if (cached_class_file != NULL) { + // JVMTI: we have an InstanceKlass now, tell it about the cached bytes + this_klass->set_cached_class_file(cached_class_file); + } + + // Fill in field values obtained by parse_classfile_attributes + if (parsed_annotations.has_any_annotations()) + parsed_annotations.apply_to(this_klass); + apply_parsed_class_attributes(this_klass); + + // Miranda methods + if ((num_miranda_methods > 0) || + // if this class introduced new miranda methods or + (super_klass.not_null() && (super_klass->has_miranda_methods())) + // super class exists and this class inherited miranda methods + ) { + this_klass->set_has_miranda_methods(); // then set a flag + } + + // Fill in information needed to compute superclasses. + this_klass->initialize_supers(super_klass(), CHECK_(nullHandle)); + + // Initialize itable offset tables + klassItable::setup_itable_offset_table(this_klass); + + // Compute transitive closure of interfaces this class implements + // Do final class setup + fill_oop_maps(this_klass, info.nonstatic_oop_map_count, info.nonstatic_oop_offsets, info.nonstatic_oop_counts); + + // Fill in has_finalizer, has_vanilla_constructor, and layout_helper + set_precomputed_flags(this_klass); + + // reinitialize modifiers, using the InnerClasses attribute + int computed_modifiers = this_klass->compute_modifier_flags(CHECK_(nullHandle)); + this_klass->set_modifier_flags(computed_modifiers); + + // check if this class can access its super class + check_super_class_access(this_klass, CHECK_(nullHandle)); + + // check if this class can access its superinterfaces + check_super_interface_access(this_klass, CHECK_(nullHandle)); + + // check if this class overrides any final method + check_final_method_override(this_klass, CHECK_(nullHandle)); + + // check that if this class is an interface then it doesn't have static methods + if (this_klass->is_interface()) { + /* An interface in a JAVA 8 classfile can be static */ + if (_major_version < JAVA_8_VERSION) { + check_illegal_static_method(this_klass, CHECK_(nullHandle)); + } + } + + // Allocate mirror and initialize static fields + java_lang_Class::create_mirror(this_klass, class_loader, protection_domain, + CHECK_(nullHandle)); + + // Generate any default methods - default methods are interface methods + // that have a default implementation. This is new with Lambda project. + if (has_default_methods ) { + DefaultMethods::generate_default_methods( + this_klass(), &all_mirandas, CHECK_(nullHandle)); + } + + // Update the loader_data graph. + record_defined_class_dependencies(this_klass, CHECK_NULL); + + ClassLoadingService::notify_class_loaded(InstanceKlass::cast(this_klass()), + false /* not shared class */); + + if (TraceClassLoading) { + ResourceMark rm; + // print in a single call to reduce interleaving of output + if (cfs->source() != NULL) { + tty->print("[Loaded %s from %s]\n", this_klass->external_name(), + cfs->source()); + } else if (class_loader.is_null()) { + Klass* caller = + THREAD->is_Java_thread() + ? ((JavaThread*)THREAD)->security_get_caller_class(1) + : NULL; + // caller can be NULL, for example, during a JVMTI VM_Init hook + if (caller != NULL) { + tty->print("[Loaded %s by instance of %s]\n", + this_klass->external_name(), + InstanceKlass::cast(caller)->external_name()); + } else { + tty->print("[Loaded %s]\n", this_klass->external_name()); + } + } else { + tty->print("[Loaded %s from %s]\n", this_klass->external_name(), + InstanceKlass::cast(class_loader->klass())->external_name()); + } + } + + if (TraceClassResolution) { + ResourceMark rm; + // print out the superclass. + const char * from = this_klass()->external_name(); + if (this_klass->java_super() != NULL) { + tty->print("RESOLVE %s %s (super)\n", from, InstanceKlass::cast(this_klass->java_super())->external_name()); + } + // print out each of the interface classes referred to by this class. + Array* local_interfaces = this_klass->local_interfaces(); + if (local_interfaces != NULL) { + int length = local_interfaces->length(); + for (int i = 0; i < length; i++) { + Klass* k = local_interfaces->at(i); + InstanceKlass* to_class = InstanceKlass::cast(k); + const char * to = to_class->external_name(); + tty->print("RESOLVE %s %s (interface)\n", from, to); + } + } + } + + // preserve result across HandleMark + preserve_this_klass = this_klass(); + } + + // Create new handle outside HandleMark (might be needed for + // Extended Class Redefinition) + instanceKlassHandle this_klass (THREAD, preserve_this_klass); + debug_only(this_klass->verify();) + + // Clear class if no error has occurred so destructor doesn't deallocate it + _klass = NULL; + return this_klass; +} + +// Destructor to clean up if there's an error +ClassFileParser::~ClassFileParser() { + MetadataFactory::free_metadata(_loader_data, _cp); + MetadataFactory::free_array(_loader_data, _fields); + + // Free methods + InstanceKlass::deallocate_methods(_loader_data, _methods); + + // beware of the Universe::empty_blah_array!! + if (_inner_classes != Universe::the_empty_short_array()) { + MetadataFactory::free_array(_loader_data, _inner_classes); + } + + // Free interfaces + InstanceKlass::deallocate_interfaces(_loader_data, _super_klass(), + _local_interfaces, _transitive_interfaces); + + MetadataFactory::free_array(_loader_data, _annotations); + MetadataFactory::free_array(_loader_data, _type_annotations); + Annotations::free_contents(_loader_data, _fields_annotations); + Annotations::free_contents(_loader_data, _fields_type_annotations); + + clear_class_metadata(); + + // deallocate the klass if already created. Don't directly deallocate, but add + // to the deallocate list so that the klass is removed from the CLD::_klasses list + // at a safepoint. + if (_klass != NULL) { + _loader_data->add_to_deallocate_list(_klass); + } + _klass = NULL; +} + +void ClassFileParser::print_field_layout(Symbol* name, + Array* fields, + constantPoolHandle cp, + int instance_size, + int instance_fields_start, + int instance_fields_end, + int static_fields_end) { + tty->print("%s: field layout\n", name->as_klass_external_name()); + tty->print(" @%3d %s\n", instance_fields_start, "--- instance fields start ---"); + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { + if (!fs.access_flags().is_static()) { + tty->print(" @%3d \"%s\" %s\n", + fs.offset(), + fs.name()->as_klass_external_name(), + fs.signature()->as_klass_external_name()); + } + } + tty->print(" @%3d %s\n", instance_fields_end, "--- instance fields end ---"); + tty->print(" @%3d %s\n", instance_size * wordSize, "--- instance ends ---"); + tty->print(" @%3d %s\n", InstanceMirrorKlass::offset_of_static_fields(), "--- static fields start ---"); + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { + if (fs.access_flags().is_static()) { + tty->print(" @%3d \"%s\" %s\n", + fs.offset(), + fs.name()->as_klass_external_name(), + fs.signature()->as_klass_external_name()); + } + } + tty->print(" @%3d %s\n", static_fields_end, "--- static fields end ---"); + tty->print("\n"); +} + +unsigned int +ClassFileParser::compute_oop_map_count(instanceKlassHandle super, + unsigned int nonstatic_oop_map_count, + int first_nonstatic_oop_offset) { + unsigned int map_count = + super.is_null() ? 0 : super->nonstatic_oop_map_count(); + if (nonstatic_oop_map_count > 0) { + // We have oops to add to map + if (map_count == 0) { + map_count = nonstatic_oop_map_count; + } else { + // Check whether we should add a new map block or whether the last one can + // be extended + OopMapBlock* const first_map = super->start_of_nonstatic_oop_maps(); + OopMapBlock* const last_map = first_map + map_count - 1; + + int next_offset = last_map->offset() + last_map->count() * heapOopSize; + if (next_offset == first_nonstatic_oop_offset) { + // There is no gap bettwen superklass's last oop field and first + // local oop field, merge maps. + nonstatic_oop_map_count -= 1; + } else { + // Superklass didn't end with a oop field, add extra maps + assert(next_offset < first_nonstatic_oop_offset, "just checking"); + } + map_count += nonstatic_oop_map_count; + } + } + return map_count; +} + + +void ClassFileParser::fill_oop_maps(instanceKlassHandle k, + unsigned int nonstatic_oop_map_count, + int* nonstatic_oop_offsets, + unsigned int* nonstatic_oop_counts) { + OopMapBlock* this_oop_map = k->start_of_nonstatic_oop_maps(); + const InstanceKlass* const super = k->superklass(); + const unsigned int super_count = super ? super->nonstatic_oop_map_count() : 0; + if (super_count > 0) { + // Copy maps from superklass + OopMapBlock* super_oop_map = super->start_of_nonstatic_oop_maps(); + for (unsigned int i = 0; i < super_count; ++i) { + *this_oop_map++ = *super_oop_map++; + } + } + + if (nonstatic_oop_map_count > 0) { + if (super_count + nonstatic_oop_map_count > k->nonstatic_oop_map_count()) { + // The counts differ because there is no gap between superklass's last oop + // field and the first local oop field. Extend the last oop map copied + // from the superklass instead of creating new one. + nonstatic_oop_map_count--; + nonstatic_oop_offsets++; + this_oop_map--; + this_oop_map->set_count(this_oop_map->count() + *nonstatic_oop_counts++); + this_oop_map++; + } + + // Add new map blocks, fill them + while (nonstatic_oop_map_count-- > 0) { + this_oop_map->set_offset(*nonstatic_oop_offsets++); + this_oop_map->set_count(*nonstatic_oop_counts++); + this_oop_map++; + } + assert(k->start_of_nonstatic_oop_maps() + k->nonstatic_oop_map_count() == + this_oop_map, "sanity"); + } +} + + +void ClassFileParser::set_precomputed_flags(instanceKlassHandle k) { + Klass* super = k->super(); + + // Check if this klass has an empty finalize method (i.e. one with return bytecode only), + // in which case we don't have to register objects as finalizable + if (!_has_empty_finalizer) { + if (_has_finalizer || + (super != NULL && super->has_finalizer())) { + k->set_has_finalizer(); + } + } + +#ifdef ASSERT + bool f = false; + Method* m = k->lookup_method(vmSymbols::finalize_method_name(), + vmSymbols::void_method_signature()); + if (m != NULL && !m->is_empty_method()) { + f = true; + } + + // Spec doesn't prevent agent from redefinition of empty finalizer. + // Despite the fact that it's generally bad idea and redefined finalizer + // will not work as expected we shouldn't abort vm in this case + if (!k->has_redefined_this_or_super()) { + assert(f == k->has_finalizer(), "inconsistent has_finalizer"); + } +#endif + + // Check if this klass supports the java.lang.Cloneable interface + if (SystemDictionary::Cloneable_klass_loaded()) { + if (k->is_subtype_of(SystemDictionary::Cloneable_klass())) { + k->set_is_cloneable(); + } + } + + // Check if this klass has a vanilla default constructor + if (super == NULL) { + // java.lang.Object has empty default constructor + k->set_has_vanilla_constructor(); + } else { + if (super->has_vanilla_constructor() && + _has_vanilla_constructor) { + k->set_has_vanilla_constructor(); + } +#ifdef ASSERT + bool v = false; + if (super->has_vanilla_constructor()) { + Method* constructor = k->find_method(vmSymbols::object_initializer_name( +), vmSymbols::void_method_signature()); + if (constructor != NULL && constructor->is_vanilla_constructor()) { + v = true; + } + } + assert(v == k->has_vanilla_constructor(), "inconsistent has_vanilla_constructor"); +#endif + } + + // If it cannot be fast-path allocated, set a bit in the layout helper. + // See documentation of InstanceKlass::can_be_fastpath_allocated(). + assert(k->size_helper() > 0, "layout_helper is initialized"); + if ((!RegisterFinalizersAtInit && k->has_finalizer()) + || k->is_abstract() || k->is_interface() + || (k->name() == vmSymbols::java_lang_Class() && k->class_loader() == NULL) + || k->size_helper() >= FastAllocateSizeLimit) { + // Forbid fast-path allocation. + jint lh = Klass::instance_layout_helper(k->size_helper(), true); + k->set_layout_helper(lh); + } +} + +// Attach super classes and interface classes to class loader data +void ClassFileParser::record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS) { + ClassLoaderData * defining_loader_data = defined_klass->class_loader_data(); + if (defining_loader_data->is_the_null_class_loader_data()) { + // Dependencies to null class loader data are implicit. + return; + } else { + // add super class dependency + Klass* super = defined_klass->super(); + if (super != NULL) { + defining_loader_data->record_dependency(super, CHECK); + } + + // add super interface dependencies + Array* local_interfaces = defined_klass->local_interfaces(); + if (local_interfaces != NULL) { + int length = local_interfaces->length(); + for (int i = 0; i < length; i++) { + defining_loader_data->record_dependency(local_interfaces->at(i), CHECK); + } + } + } +} + +// utility methods for appending an array with check for duplicates + +void append_interfaces(GrowableArray* result, Array* ifs) { + // iterate over new interfaces + for (int i = 0; i < ifs->length(); i++) { + Klass* e = ifs->at(i); + assert(e->is_klass() && InstanceKlass::cast(e)->is_interface(), "just checking"); + // add new interface + result->append_if_missing(e); + } +} + +Array* ClassFileParser::compute_transitive_interfaces( + instanceKlassHandle super, + Array* local_ifs, TRAPS) { + // Compute maximum size for transitive interfaces + int max_transitive_size = 0; + int super_size = 0; + // Add superclass transitive interfaces size + if (super.not_null()) { + super_size = super->transitive_interfaces()->length(); + max_transitive_size += super_size; + } + // Add local interfaces' super interfaces + int local_size = local_ifs->length(); + for (int i = 0; i < local_size; i++) { + Klass* l = local_ifs->at(i); + max_transitive_size += InstanceKlass::cast(l)->transitive_interfaces()->length(); + } + // Finally add local interfaces + max_transitive_size += local_size; + // Construct array + if (max_transitive_size == 0) { + // no interfaces, use canonicalized array + return Universe::the_empty_klass_array(); + } else if (max_transitive_size == super_size) { + // no new local interfaces added, share superklass' transitive interface array + return super->transitive_interfaces(); + } else if (max_transitive_size == local_size) { + // only local interfaces added, share local interface array + return local_ifs; + } else { + ResourceMark rm; + GrowableArray* result = new GrowableArray(max_transitive_size); + + // Copy down from superclass + if (super.not_null()) { + append_interfaces(result, super->transitive_interfaces()); + } + + // Copy down from local interfaces' superinterfaces + for (int i = 0; i < local_ifs->length(); i++) { + Klass* l = local_ifs->at(i); + append_interfaces(result, InstanceKlass::cast(l)->transitive_interfaces()); + } + // Finally add local interfaces + append_interfaces(result, local_ifs); + + // length will be less than the max_transitive_size if duplicates were removed + int length = result->length(); + assert(length <= max_transitive_size, "just checking"); + Array* new_result = MetadataFactory::new_array(_loader_data, length, CHECK_NULL); + for (int i = 0; i < length; i++) { + Klass* e = result->at(i); + assert(e != NULL, "just checking"); + new_result->at_put(i, e); + } + return new_result; + } +} + +void ClassFileParser::check_super_class_access(instanceKlassHandle this_klass, TRAPS) { + Klass* super = this_klass->super(); + if ((super != NULL) && + (!Reflection::verify_class_access(this_klass(), super, false))) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_IllegalAccessError(), + "class %s cannot access its superclass %s", + this_klass->external_name(), + InstanceKlass::cast(super)->external_name() + ); + return; + } +} + + +void ClassFileParser::check_super_interface_access(instanceKlassHandle this_klass, TRAPS) { + Array* local_interfaces = this_klass->local_interfaces(); + int lng = local_interfaces->length(); + for (int i = lng - 1; i >= 0; i--) { + Klass* k = local_interfaces->at(i); + assert (k != NULL && k->is_interface(), "invalid interface"); + if (!Reflection::verify_class_access(this_klass(), k, false)) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_IllegalAccessError(), + "class %s cannot access its superinterface %s", + this_klass->external_name(), + InstanceKlass::cast(k)->external_name() + ); + return; + } + } +} + + +void ClassFileParser::check_final_method_override(instanceKlassHandle this_klass, TRAPS) { + Array* methods = this_klass->methods(); + int num_methods = methods->length(); + + // go thru each method and check if it overrides a final method + for (int index = 0; index < num_methods; index++) { + Method* m = methods->at(index); + + // skip private, static, and methods + if ((!m->is_private() && !m->is_static()) && + (m->name() != vmSymbols::object_initializer_name())) { + + Symbol* name = m->name(); + Symbol* signature = m->signature(); + Klass* k = this_klass->super(); + Method* super_m = NULL; + while (k != NULL) { + // skip supers that don't have final methods. + if (k->has_final_method()) { + // lookup a matching method in the super class hierarchy + super_m = InstanceKlass::cast(k)->lookup_method(name, signature); + if (super_m == NULL) { + break; // didn't find any match; get out + } + + if (super_m->is_final() && !super_m->is_static() && + // matching method in super is final, and not static + (Reflection::verify_field_access(this_klass(), + super_m->method_holder(), + super_m->method_holder(), + super_m->access_flags(), false)) + // this class can access super final method and therefore override + ) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_VerifyError(), + "class %s overrides final method %s.%s%s", + this_klass->external_name(), + super_m->method_holder()->external_name(), + name->as_C_string(), + signature->as_C_string() + ); + return; + } + + // continue to look from super_m's holder's super. + k = super_m->method_holder()->super(); + continue; + } + + k = k->super(); + } + } + } +} + + +// assumes that this_klass is an interface +void ClassFileParser::check_illegal_static_method(instanceKlassHandle this_klass, TRAPS) { + assert(this_klass->is_interface(), "not an interface"); + Array* methods = this_klass->methods(); + int num_methods = methods->length(); + + for (int index = 0; index < num_methods; index++) { + Method* m = methods->at(index); + // if m is static and not the init method, throw a verify error + if ((m->is_static()) && (m->name() != vmSymbols::class_initializer_name())) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_VerifyError(), + "Illegal static method %s in interface %s", + m->name()->as_C_string(), + this_klass->external_name() + ); + return; + } + } +} + +// utility methods for format checking + +void ClassFileParser::verify_legal_class_modifiers(jint flags, TRAPS) { + if (!_need_verify) { return; } + + const bool is_interface = (flags & JVM_ACC_INTERFACE) != 0; + const bool is_abstract = (flags & JVM_ACC_ABSTRACT) != 0; + const bool is_final = (flags & JVM_ACC_FINAL) != 0; + const bool is_super = (flags & JVM_ACC_SUPER) != 0; + const bool is_enum = (flags & JVM_ACC_ENUM) != 0; + const bool is_annotation = (flags & JVM_ACC_ANNOTATION) != 0; + const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION; + + if ((is_abstract && is_final) || + (is_interface && !is_abstract) || + (is_interface && major_gte_15 && (is_super || is_enum)) || + (!is_interface && major_gte_15 && is_annotation)) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_ClassFormatError(), + "Illegal class modifiers in class %s: 0x%X", + _class_name->as_C_string(), flags + ); + return; + } +} + +bool ClassFileParser::has_illegal_visibility(jint flags) { + const bool is_public = (flags & JVM_ACC_PUBLIC) != 0; + const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0; + const bool is_private = (flags & JVM_ACC_PRIVATE) != 0; + + return ((is_public && is_protected) || + (is_public && is_private) || + (is_protected && is_private)); +} + +bool ClassFileParser::is_supported_version(u2 major, u2 minor) { + u2 max_version = JAVA_MAX_SUPPORTED_VERSION; + return (major >= JAVA_MIN_SUPPORTED_VERSION) && + (major <= max_version) && + ((major != max_version) || + (minor <= JAVA_MAX_SUPPORTED_MINOR_VERSION)); +} + +void ClassFileParser::verify_legal_field_modifiers( + jint flags, bool is_interface, TRAPS) { + if (!_need_verify) { return; } + + const bool is_public = (flags & JVM_ACC_PUBLIC) != 0; + const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0; + const bool is_private = (flags & JVM_ACC_PRIVATE) != 0; + const bool is_static = (flags & JVM_ACC_STATIC) != 0; + const bool is_final = (flags & JVM_ACC_FINAL) != 0; + const bool is_volatile = (flags & JVM_ACC_VOLATILE) != 0; + const bool is_transient = (flags & JVM_ACC_TRANSIENT) != 0; + const bool is_enum = (flags & JVM_ACC_ENUM) != 0; + const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION; + + bool is_illegal = false; + + if (is_interface) { + if (!is_public || !is_static || !is_final || is_private || + is_protected || is_volatile || is_transient || + (major_gte_15 && is_enum)) { + is_illegal = true; + } + } else { // not interface + if (has_illegal_visibility(flags) || (is_final && is_volatile)) { + is_illegal = true; + } + } + + if (is_illegal) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_ClassFormatError(), + "Illegal field modifiers in class %s: 0x%X", + _class_name->as_C_string(), flags); + return; + } +} + +void ClassFileParser::verify_legal_method_modifiers( + jint flags, bool is_interface, Symbol* name, TRAPS) { + if (!_need_verify) { return; } + + const bool is_public = (flags & JVM_ACC_PUBLIC) != 0; + const bool is_private = (flags & JVM_ACC_PRIVATE) != 0; + const bool is_static = (flags & JVM_ACC_STATIC) != 0; + const bool is_final = (flags & JVM_ACC_FINAL) != 0; + const bool is_native = (flags & JVM_ACC_NATIVE) != 0; + const bool is_abstract = (flags & JVM_ACC_ABSTRACT) != 0; + const bool is_bridge = (flags & JVM_ACC_BRIDGE) != 0; + const bool is_strict = (flags & JVM_ACC_STRICT) != 0; + const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 0; + const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0; + const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION; + const bool major_gte_8 = _major_version >= JAVA_8_VERSION; + const bool is_initializer = (name == vmSymbols::object_initializer_name()); + + bool is_illegal = false; + + if (is_interface) { + if (major_gte_8) { + // Class file version is JAVA_8_VERSION or later Methods of + // interfaces may set any of the flags except ACC_PROTECTED, + // ACC_FINAL, ACC_NATIVE, and ACC_SYNCHRONIZED; they must + // have exactly one of the ACC_PUBLIC or ACC_PRIVATE flags set. + if ((is_public == is_private) || /* Only one of private and public should be true - XNOR */ + (is_native || is_protected || is_final || is_synchronized) || + // If a specific method of a class or interface has its + // ACC_ABSTRACT flag set, it must not have any of its + // ACC_FINAL, ACC_NATIVE, ACC_PRIVATE, ACC_STATIC, + // ACC_STRICT, or ACC_SYNCHRONIZED flags set. No need to + // check for ACC_FINAL, ACC_NATIVE or ACC_SYNCHRONIZED as + // those flags are illegal irrespective of ACC_ABSTRACT being set or not. + (is_abstract && (is_private || is_static || is_strict))) { + is_illegal = true; + } + } else if (major_gte_15) { + // Class file version in the interval [JAVA_1_5_VERSION, JAVA_8_VERSION) + if (!is_public || is_static || is_final || is_synchronized || + is_native || !is_abstract || is_strict) { + is_illegal = true; + } + } else { + // Class file version is pre-JAVA_1_5_VERSION + if (!is_public || is_static || is_final || is_native || !is_abstract) { + is_illegal = true; + } + } + } else { // not interface + if (is_initializer) { + if (is_static || is_final || is_synchronized || is_native || + is_abstract || (major_gte_15 && is_bridge)) { + is_illegal = true; + } + } else { // not initializer + if (is_abstract) { + if ((is_final || is_native || is_private || is_static || + (major_gte_15 && (is_synchronized || is_strict)))) { + is_illegal = true; + } + } + if (has_illegal_visibility(flags)) { + is_illegal = true; + } + } + } + + if (is_illegal) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_ClassFormatError(), + "Method %s in class %s has illegal modifiers: 0x%X", + name->as_C_string(), _class_name->as_C_string(), flags); + return; + } +} + +void ClassFileParser::verify_legal_utf8(const unsigned char* buffer, int length, TRAPS) { + assert(_need_verify, "only called when _need_verify is true"); + int i = 0; + int count = length >> 2; + for (int k=0; k= 128 (highest bit 1) for v == 0 or v >= 128. + unsigned char res = b0 | b0 - 1 | + b1 | b1 - 1 | + b2 | b2 - 1 | + b3 | b3 - 1; + if (res >= 128) break; + i += 4; + } + for(; i < length; i++) { + unsigned short c; + // no embedded zeros + guarantee_property((buffer[i] != 0), "Illegal UTF8 string in constant pool in class file %s", CHECK); + if(buffer[i] < 128) { + continue; + } + if ((i + 5) < length) { // see if it's legal supplementary character + if (UTF8::is_supplementary_character(&buffer[i])) { + c = UTF8::get_supplementary_character(&buffer[i]); + i += 5; + continue; + } + } + switch (buffer[i] >> 4) { + default: break; + case 0x8: case 0x9: case 0xA: case 0xB: case 0xF: + classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK); + case 0xC: case 0xD: // 110xxxxx 10xxxxxx + c = (buffer[i] & 0x1F) << 6; + i++; + if ((i < length) && ((buffer[i] & 0xC0) == 0x80)) { + c += buffer[i] & 0x3F; + if (_major_version <= 47 || c == 0 || c >= 0x80) { + // for classes with major > 47, c must a null or a character in its shortest form + break; + } + } + classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK); + case 0xE: // 1110xxxx 10xxxxxx 10xxxxxx + c = (buffer[i] & 0xF) << 12; + i += 2; + if ((i < length) && ((buffer[i-1] & 0xC0) == 0x80) && ((buffer[i] & 0xC0) == 0x80)) { + c += ((buffer[i-1] & 0x3F) << 6) + (buffer[i] & 0x3F); + if (_major_version <= 47 || c >= 0x800) { + // for classes with major > 47, c must be in its shortest form + break; + } + } + classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK); + } // end of switch + } // end of for +} + +// Checks if name is a legal class name. +void ClassFileParser::verify_legal_class_name(Symbol* name, TRAPS) { + if (!_need_verify || _relax_verify) { return; } + + char buf[fixed_buffer_size]; + char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); + unsigned int length = name->utf8_length(); + bool legal = false; + + if (length > 0) { + char* p; + if (bytes[0] == JVM_SIGNATURE_ARRAY) { + p = skip_over_field_signature(bytes, false, length, CHECK); + legal = (p != NULL) && ((p - bytes) == (int)length); + } else if (_major_version < JAVA_1_5_VERSION) { + if (bytes[0] != '<') { + p = skip_over_field_name(bytes, true, length); + legal = (p != NULL) && ((p - bytes) == (int)length); + } + } else { + // 4900761: relax the constraints based on JSR202 spec + // Class names may be drawn from the entire Unicode character set. + // Identifiers between '/' must be unqualified names. + // The utf8 string has been verified when parsing cpool entries. + legal = verify_unqualified_name(bytes, length, LegalClass); + } + } + if (!legal) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_ClassFormatError(), + "Illegal class name \"%s\" in class file %s", bytes, + _class_name->as_C_string() + ); + return; + } +} + +// Checks if name is a legal field name. +void ClassFileParser::verify_legal_field_name(Symbol* name, TRAPS) { + if (!_need_verify || _relax_verify) { return; } + + char buf[fixed_buffer_size]; + char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); + unsigned int length = name->utf8_length(); + bool legal = false; + + if (length > 0) { + if (_major_version < JAVA_1_5_VERSION) { + if (bytes[0] != '<') { + char* p = skip_over_field_name(bytes, false, length); + legal = (p != NULL) && ((p - bytes) == (int)length); + } + } else { + // 4881221: relax the constraints based on JSR202 spec + legal = verify_unqualified_name(bytes, length, LegalField); + } + } + + if (!legal) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_ClassFormatError(), + "Illegal field name \"%s\" in class %s", bytes, + _class_name->as_C_string() + ); + return; + } +} + +// Checks if name is a legal method name. +void ClassFileParser::verify_legal_method_name(Symbol* name, TRAPS) { + if (!_need_verify || _relax_verify) { return; } + + assert(name != NULL, "method name is null"); + char buf[fixed_buffer_size]; + char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); + unsigned int length = name->utf8_length(); + bool legal = false; + + if (length > 0) { + if (bytes[0] == '<') { + if (name == vmSymbols::object_initializer_name() || name == vmSymbols::class_initializer_name()) { + legal = true; + } + } else if (_major_version < JAVA_1_5_VERSION) { + char* p; + p = skip_over_field_name(bytes, false, length); + legal = (p != NULL) && ((p - bytes) == (int)length); + } else { + // 4881221: relax the constraints based on JSR202 spec + legal = verify_unqualified_name(bytes, length, LegalMethod); + } + } + + if (!legal) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_ClassFormatError(), + "Illegal method name \"%s\" in class %s", bytes, + _class_name->as_C_string() + ); + return; + } +} + + +// Checks if signature is a legal field signature. +void ClassFileParser::verify_legal_field_signature(Symbol* name, Symbol* signature, TRAPS) { + if (!_need_verify) { return; } + + char buf[fixed_buffer_size]; + char* bytes = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); + unsigned int length = signature->utf8_length(); + char* p = skip_over_field_signature(bytes, false, length, CHECK); + + if (p == NULL || (p - bytes) != (int)length) { + throwIllegalSignature("Field", name, signature, CHECK); + } +} + +// Checks if signature is a legal method signature. +// Returns number of parameters +int ClassFileParser::verify_legal_method_signature(Symbol* name, Symbol* signature, TRAPS) { + if (!_need_verify) { + // make sure caller's args_size will be less than 0 even for non-static + // method so it will be recomputed in compute_size_of_parameters(). + return -2; + } + + unsigned int args_size = 0; + char buf[fixed_buffer_size]; + char* p = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); + unsigned int length = signature->utf8_length(); + char* nextp; + + // The first character must be a '(' + if ((length > 0) && (*p++ == JVM_SIGNATURE_FUNC)) { + length--; + // Skip over legal field signatures + nextp = skip_over_field_signature(p, false, length, CHECK_0); + while ((length > 0) && (nextp != NULL)) { + args_size++; + if (p[0] == 'J' || p[0] == 'D') { + args_size++; + } + length -= nextp - p; + p = nextp; + nextp = skip_over_field_signature(p, false, length, CHECK_0); + } + // The first non-signature thing better be a ')' + if ((length > 0) && (*p++ == JVM_SIGNATURE_ENDFUNC)) { + length--; + if (name->utf8_length() > 0 && name->byte_at(0) == '<') { + // All internal methods must return void + if ((length == 1) && (p[0] == JVM_SIGNATURE_VOID)) { + return args_size; + } + } else { + // Now we better just have a return value + nextp = skip_over_field_signature(p, true, length, CHECK_0); + if (nextp && ((int)length == (nextp - p))) { + return args_size; + } + } + } + } + // Report error + throwIllegalSignature("Method", name, signature, CHECK_0); + return 0; +} + + +// Unqualified names may not contain the characters '.', ';', '[', or '/'. +// Method names also may not contain the characters '<' or '>', unless +// or . Note that method names may not be or in this +// method. Because these names have been checked as special cases before +// calling this method in verify_legal_method_name. +bool ClassFileParser::verify_unqualified_name( + char* name, unsigned int length, int type) { + jchar ch; + + for (char* p = name; p != name + length; ) { + ch = *p; + if (ch < 128) { + p++; + if (ch == '.' || ch == ';' || ch == '[' ) { + return false; // do not permit '.', ';', or '[' + } + if (type != LegalClass && ch == '/') { + return false; // do not permit '/' unless it's class name + } + if (type == LegalMethod && (ch == '<' || ch == '>')) { + return false; // do not permit '<' or '>' in method names + } + } else { + char* tmp_p = UTF8::next(p, &ch); + p = tmp_p; + } + } + return true; +} + + +// Take pointer to a string. Skip over the longest part of the string that could +// be taken as a fieldname. Allow '/' if slash_ok is true. +// Return a pointer to just past the fieldname. +// Return NULL if no fieldname at all was found, or in the case of slash_ok +// being true, we saw consecutive slashes (meaning we were looking for a +// qualified path but found something that was badly-formed). +char* ClassFileParser::skip_over_field_name(char* name, bool slash_ok, unsigned int length) { + char* p; + jchar ch; + jboolean last_is_slash = false; + jboolean not_first_ch = false; + + for (p = name; p != name + length; not_first_ch = true) { + char* old_p = p; + ch = *p; + if (ch < 128) { + p++; + // quick check for ascii + if ((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch == '_' || ch == '$') || + (not_first_ch && ch >= '0' && ch <= '9')) { + last_is_slash = false; + continue; + } + if (slash_ok && ch == '/') { + if (last_is_slash) { + return NULL; // Don't permit consecutive slashes + } + last_is_slash = true; + continue; + } + } else { + jint unicode_ch; + char* tmp_p = UTF8::next_character(p, &unicode_ch); + p = tmp_p; + last_is_slash = false; + // Check if ch is Java identifier start or is Java identifier part + // 4672820: call java.lang.Character methods directly without generating separate tables. + EXCEPTION_MARK; + instanceKlassHandle klass (THREAD, SystemDictionary::Character_klass()); + + // return value + JavaValue result(T_BOOLEAN); + // Set up the arguments to isJavaIdentifierStart and isJavaIdentifierPart + JavaCallArguments args; + args.push_int(unicode_ch); + + // public static boolean isJavaIdentifierStart(char ch); + JavaCalls::call_static(&result, + klass, + vmSymbols::isJavaIdentifierStart_name(), + vmSymbols::int_bool_signature(), + &args, + THREAD); + + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + return 0; + } + if (result.get_jboolean()) { + continue; + } + + if (not_first_ch) { + // public static boolean isJavaIdentifierPart(char ch); + JavaCalls::call_static(&result, + klass, + vmSymbols::isJavaIdentifierPart_name(), + vmSymbols::int_bool_signature(), + &args, + THREAD); + + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + return 0; + } + + if (result.get_jboolean()) { + continue; + } + } + } + return (not_first_ch) ? old_p : NULL; + } + return (not_first_ch) ? p : NULL; +} + + +// Take pointer to a string. Skip over the longest part of the string that could +// be taken as a field signature. Allow "void" if void_ok. +// Return a pointer to just past the signature. +// Return NULL if no legal signature is found. +char* ClassFileParser::skip_over_field_signature(char* signature, + bool void_ok, + unsigned int length, + TRAPS) { + unsigned int array_dim = 0; + while (length > 0) { + switch (signature[0]) { + case JVM_SIGNATURE_VOID: if (!void_ok) { return NULL; } + case JVM_SIGNATURE_BOOLEAN: + case JVM_SIGNATURE_BYTE: + case JVM_SIGNATURE_CHAR: + case JVM_SIGNATURE_SHORT: + case JVM_SIGNATURE_INT: + case JVM_SIGNATURE_FLOAT: + case JVM_SIGNATURE_LONG: + case JVM_SIGNATURE_DOUBLE: + return signature + 1; + case JVM_SIGNATURE_CLASS: { + if (_major_version < JAVA_1_5_VERSION) { + // Skip over the class name if one is there + char* p = skip_over_field_name(signature + 1, true, --length); + + // The next character better be a semicolon + if (p && (p - signature) > 1 && p[0] == ';') { + return p + 1; + } + } else { + // 4900761: For class version > 48, any unicode is allowed in class name. + length--; + signature++; + while (length > 0 && signature[0] != ';') { + if (signature[0] == '.') { + classfile_parse_error("Class name contains illegal character '.' in descriptor in class file %s", CHECK_0); + } + length--; + signature++; + } + if (signature[0] == ';') { return signature + 1; } + } + + return NULL; + } + case JVM_SIGNATURE_ARRAY: + array_dim++; + if (array_dim > 255) { + // 4277370: array descriptor is valid only if it represents 255 or fewer dimensions. + classfile_parse_error("Array type descriptor has more than 255 dimensions in class file %s", CHECK_0); + } + // The rest of what's there better be a legal signature + signature++; + length--; + void_ok = false; + break; + + default: + return NULL; + } + } + return NULL; +} diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp index 6ce366a21f8..b2efa8ceba3 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.hpp +++ b/hotspot/src/share/vm/classfile/classFileParser.hpp @@ -247,7 +247,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { Array* parse_methods(bool is_interface, AccessFlags* promoted_flags, bool* has_final_method, - bool* has_default_method, + bool* declares_default_methods, TRAPS); intArray* sort_methods(Array* methods); diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 8ea08cd54c7..1ef55c6875d 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -736,6 +736,41 @@ void InstanceKlass::link_methods(TRAPS) { } } +// Eagerly initialize superinterfaces that declare default methods (concrete instance: any access) +void InstanceKlass::initialize_super_interfaces(instanceKlassHandle this_k, TRAPS) { + if (this_k->has_default_methods()) { + for (int i = 0; i < this_k->local_interfaces()->length(); ++i) { + Klass* iface = this_k->local_interfaces()->at(i); + InstanceKlass* ik = InstanceKlass::cast(iface); + if (ik->should_be_initialized()) { + if (ik->has_default_methods()) { + ik->initialize_super_interfaces(ik, THREAD); + } + // Only initialize() interfaces that "declare" concrete methods. + // has_default_methods drives searching superinterfaces since it + // means has_default_methods in its superinterface hierarchy + if (!HAS_PENDING_EXCEPTION && ik->declares_default_methods()) { + ik->initialize(THREAD); + } + if (HAS_PENDING_EXCEPTION) { + Handle e(THREAD, PENDING_EXCEPTION); + CLEAR_PENDING_EXCEPTION; + { + EXCEPTION_MARK; + // Locks object, set state, and notify all waiting threads + this_k->set_initialization_state_and_notify( + initialization_error, THREAD); + + // ignore any exception thrown, superclass initialization error is + // thrown below + CLEAR_PENDING_EXCEPTION; + } + THROW_OOP(e()); + } + } + } + } +} void InstanceKlass::initialize_impl(instanceKlassHandle this_k, TRAPS) { // Make sure klass is linked (verified) before initialization @@ -815,33 +850,11 @@ void InstanceKlass::initialize_impl(instanceKlassHandle this_k, TRAPS) { } } + // Recursively initialize any superinterfaces that declare default methods + // Only need to recurse if has_default_methods which includes declaring and + // inheriting default methods if (this_k->has_default_methods()) { - // Step 7.5: initialize any interfaces which have default methods - for (int i = 0; i < this_k->local_interfaces()->length(); ++i) { - Klass* iface = this_k->local_interfaces()->at(i); - InstanceKlass* ik = InstanceKlass::cast(iface); - if (ik->has_default_methods() && ik->should_be_initialized()) { - ik->initialize(THREAD); - - if (HAS_PENDING_EXCEPTION) { - Handle e(THREAD, PENDING_EXCEPTION); - CLEAR_PENDING_EXCEPTION; - { - EXCEPTION_MARK; - // Locks object, set state, and notify all waiting threads - this_k->set_initialization_state_and_notify( - initialization_error, THREAD); - - // ignore any exception thrown, superclass initialization error is - // thrown below - CLEAR_PENDING_EXCEPTION; - } - DTRACE_CLASSINIT_PROBE_WAIT( - super__failed, InstanceKlass::cast(this_k()), -1, wait); - THROW_OOP(e()); - } - } - } + this_k->initialize_super_interfaces(this_k, CHECK); } // Step 8 diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index e50aa45eb69..64fb16bda64 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -199,13 +199,14 @@ class InstanceKlass: public Klass { bool _has_unloaded_dependent; enum { - _misc_rewritten = 1 << 0, // methods rewritten. - _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops - _misc_should_verify_class = 1 << 2, // allow caching of preverification - _misc_is_anonymous = 1 << 3, // has embedded _host_klass field - _misc_is_contended = 1 << 4, // marked with contended annotation - _misc_has_default_methods = 1 << 5, // class/superclass/implemented interfaces has default methods - _misc_has_been_redefined = 1 << 6 // class has been redefined + _misc_rewritten = 1 << 0, // methods rewritten. + _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops + _misc_should_verify_class = 1 << 2, // allow caching of preverification + _misc_is_anonymous = 1 << 3, // has embedded _host_klass field + _misc_is_contended = 1 << 4, // marked with contended annotation + _misc_has_default_methods = 1 << 5, // class/superclass/implemented interfaces has default methods + _misc_declares_default_methods = 1 << 6, // directly declares default methods (any access) + _misc_has_been_redefined = 1 << 7 // class has been redefined }; u2 _misc_flags; u2 _minor_version; // minor version number of class file @@ -651,6 +652,17 @@ class InstanceKlass: public Klass { } } + bool declares_default_methods() const { + return (_misc_flags & _misc_declares_default_methods) != 0; + } + void set_declares_default_methods(bool b) { + if (b) { + _misc_flags |= _misc_declares_default_methods; + } else { + _misc_flags &= ~_misc_declares_default_methods; + } + } + // for adding methods, ConstMethod::UNSET_IDNUM means no more ids available inline u2 next_method_idnum(); void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; } @@ -1022,6 +1034,7 @@ private: static bool link_class_impl (instanceKlassHandle this_k, bool throw_verifyerror, TRAPS); static bool verify_code (instanceKlassHandle this_k, bool throw_verifyerror, TRAPS); static void initialize_impl (instanceKlassHandle this_k, TRAPS); + static void initialize_super_interfaces (instanceKlassHandle this_k, TRAPS); static void eager_initialize_impl (instanceKlassHandle this_k); static void set_initialization_state_and_notify_impl (instanceKlassHandle this_k, ClassState state, TRAPS); static void call_class_initializer_impl (instanceKlassHandle this_k, TRAPS); diff --git a/hotspot/src/share/vm/utilities/dtrace_disabled.hpp b/hotspot/src/share/vm/utilities/dtrace_disabled.hpp index 2906fe22e93..40093592791 100644 --- a/hotspot/src/share/vm/utilities/dtrace_disabled.hpp +++ b/hotspot/src/share/vm/utilities/dtrace_disabled.hpp @@ -27,7 +27,7 @@ /* This file contains dummy provider probes needed when compiling a hotspot * that does not support dtrace probes. This could be because we're building - * on a system that doesn't suuport dtrace or because we're bulding a variant + * on a system that doesn't support dtrace or because we're bulding a variant * of hotspot (like core) where we do not support dtrace */ #if !defined(DTRACE_ENABLED) diff --git a/hotspot/test/runtime/lambda-features/InvokespecialInterface.java b/hotspot/test/runtime/lambda-features/InvokespecialInterface.java index c33dd56ef64..3b32dd7e552 100644 --- a/hotspot/test/runtime/lambda-features/InvokespecialInterface.java +++ b/hotspot/test/runtime/lambda-features/InvokespecialInterface.java @@ -33,11 +33,12 @@ import java.util.function.*; import java.util.*; +public class InvokespecialInterface { interface I { default void imethod() { System.out.println("I::imethod"); } } -class C implements I { +static class C implements I { public void foo() { I.super.imethod(); } // invokespecial InterfaceMethod public void bar() { I i = this; i.imethod(); } // invokeinterface same public void doSomeInvokedynamic() { @@ -48,7 +49,6 @@ class C implements I { } } -public class InvokespecialInterface { public static void main(java.lang.String[] unused) { // need to create C and call I::foo() C c = new C(); diff --git a/hotspot/test/runtime/lambda-features/TestInterfaceInit.java b/hotspot/test/runtime/lambda-features/TestInterfaceInit.java new file mode 100644 index 00000000000..0493a60bb1e --- /dev/null +++ b/hotspot/test/runtime/lambda-features/TestInterfaceInit.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, 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 8034275 + * @summary [JDK 8u40] Test interface initialization: only for interfaces declaring default methods + * @run main TestInterfaceInit + */ +import java.util.List; +import java.util.Arrays; +import java.util.ArrayList; + +public class TestInterfaceInit { + + static List> cInitOrder = new ArrayList<>(); + + // Declares a default method and initializes + interface I { + boolean v = TestInterfaceInit.out(I.class); + default void x() {} + } + + // Declares a default method and initializes + interface J extends I { + boolean v = TestInterfaceInit.out(J.class); + default void x() {} + } + // No default method, does not initialize + interface JN extends J { + boolean v = TestInterfaceInit.out(JN.class); + } + + // Declares a default method and initializes + interface K extends I { + boolean v = TestInterfaceInit.out(K.class); + default void x() {} + } + + // No default method, does not initialize + interface KN extends K { + boolean v = TestInterfaceInit.out(KN.class); + } + + interface L extends JN, KN { + boolean v = TestInterfaceInit.out(L.class); + default void x() {} + } + + public static void main(String[] args) { + // Trigger initialization + boolean v = L.v; + + List> expectedCInitOrder = Arrays.asList(I.class,J.class,K.class,L.class); + if (!cInitOrder.equals(expectedCInitOrder)) { + throw new RuntimeException(String.format("Class initialization array %s not equal to expected array %s", cInitOrder, expectedCInitOrder)); + } + } + + static boolean out(Class c) { + System.out.println("#: initializing " + c.getName()); + cInitOrder.add(c); + return true; + } + +} diff --git a/hotspot/test/runtime/lambda-features/TestInterfaceOrder.java b/hotspot/test/runtime/lambda-features/TestInterfaceOrder.java new file mode 100644 index 00000000000..245742ece14 --- /dev/null +++ b/hotspot/test/runtime/lambda-features/TestInterfaceOrder.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014, 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 8034275 + * @summary [JDK 8u40] Test interface initialization order + * @run main TestInterfaceOrder + */ + +import java.util.List; +import java.util.Arrays; +import java.util.ArrayList; + +public class TestInterfaceOrder { + static List> cInitOrder = new ArrayList<>(); + + public static void main(java.lang.String[] args) { + //Trigger initialization + C c = new C(); + + List> expectedCInitOrder = Arrays.asList(I.class, J.class, A.class, K.class, B.class, L.class, C.class); + if (!cInitOrder.equals(expectedCInitOrder)) { + throw new RuntimeException(String.format("Class initialization order %s not equal to expected order %s", cInitOrder, expectedCInitOrder)); + } + } + + interface I { + boolean v = TestInterfaceOrder.out(I.class); + default void i() {} + } + + interface J extends I { + boolean v = TestInterfaceOrder.out(J.class); + default void j() {} + } + + static class A implements J { + static boolean v = TestInterfaceOrder.out(A.class); + } + + interface K extends I { + boolean v = TestInterfaceOrder.out(K.class); + default void k() {} + } + + static class B extends A implements K { + static boolean v = TestInterfaceOrder.out(B.class); + } + + interface L { + boolean v = TestInterfaceOrder.out(L.class); + default void l() {} + } + + static class C extends B implements L { + static boolean v = TestInterfaceOrder.out(C.class); + } + + + static boolean out(Class c) { + System.out.println("#: initializing " + c.getName()); + cInitOrder.add(c); + return true; + } + +} From 3a3e45ab40993611bdc0795e92bc3d72eeac6878 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Thu, 23 Oct 2014 11:43:29 +0200 Subject: [PATCH 23/67] 8061630: G1 iterates over JNIHandles two times Reviewed-by: mgerdin, brutisso --- .../src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 7ac2782772b..5d1ba94cc27 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -5760,14 +5760,10 @@ void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) { // not copied during the pause. process_discovered_references(n_workers); - // Weak root processing. - { + if (G1StringDedup::is_enabled()) { G1STWIsAliveClosure is_alive(this); G1KeepAliveClosure keep_alive(this); - JNIHandles::weak_oops_do(&is_alive, &keep_alive); - if (G1StringDedup::is_enabled()) { - G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive); - } + G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive); } _allocator->release_gc_alloc_regions(n_workers, evacuation_info); From 1aa3da106723aa92da1ba3267494bbfb83ca23b6 Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Thu, 23 Oct 2014 10:08:02 -0700 Subject: [PATCH 24/67] 8038268: VM Crashes in MetaspaceShared::generate_vtable_methods while creating CDS archive with limiting SharedMiscCodeSize Estimate the minimum required size for the misc code region and check if the specified misc code region size meets the minimum size requirement Reviewed-by: jiangli, dholmes --- hotspot/src/share/vm/memory/metaspace.cpp | 10 ++++++++++ hotspot/src/share/vm/memory/metaspaceShared.hpp | 15 ++++++++++----- hotspot/src/share/vm/utilities/debug.cpp | 8 +++++--- hotspot/src/share/vm/utilities/debug.hpp | 3 ++- .../SharedArchiveFile/LimitSharedSizes.java | 9 ++++++--- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index c39c1353fe3..2f5d5843ee2 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -3157,6 +3157,16 @@ void Metaspace::global_initialize() { SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment); SharedMiscCodeSize = align_size_up(SharedMiscCodeSize, max_alignment); + // the min_misc_code_size estimate is based on MetaspaceShared::generate_vtable_methods() + uintx min_misc_code_size = align_size_up( + (MetaspaceShared::num_virtuals * MetaspaceShared::vtbl_list_size) * + (sizeof(void*) + MetaspaceShared::vtbl_method_size) + MetaspaceShared::vtbl_common_code_size, + max_alignment); + + if (SharedMiscCodeSize < min_misc_code_size) { + report_out_of_shared_space(SharedMiscCode); + } + // Initialize with the sum of the shared space sizes. The read-only // and read write metaspace chunks will be allocated out of this and the // remainder is the misc code and data chunks. diff --git a/hotspot/src/share/vm/memory/metaspaceShared.hpp b/hotspot/src/share/vm/memory/metaspaceShared.hpp index cc514c05050..db344359082 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.hpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp @@ -57,11 +57,16 @@ class MetaspaceShared : AllStatic { static bool _archive_loading_failed; public: enum { - vtbl_list_size = 17, // number of entries in the shared space vtable list. - num_virtuals = 200 // maximum number of virtual functions - // If virtual functions are added to Metadata, - // this number needs to be increased. Also, - // SharedMiscCodeSize will need to be increased. + vtbl_list_size = 17, // number of entries in the shared space vtable list. + num_virtuals = 200, // maximum number of virtual functions + // If virtual functions are added to Metadata, + // this number needs to be increased. Also, + // SharedMiscCodeSize will need to be increased. + // The following 2 sizes were based on + // MetaspaceShared::generate_vtable_methods() + vtbl_method_size = 16, // conservative size of the mov1 and jmp instructions + // for the x64 platform + vtbl_common_code_size = (1*K) // conservative size of the "common_code" for the x64 platform }; enum { diff --git a/hotspot/src/share/vm/utilities/debug.cpp b/hotspot/src/share/vm/utilities/debug.cpp index bb0195d58d1..adacdc4233f 100644 --- a/hotspot/src/share/vm/utilities/debug.cpp +++ b/hotspot/src/share/vm/utilities/debug.cpp @@ -256,16 +256,18 @@ void report_out_of_shared_space(SharedSpaceType shared_space) { static const char* name[] = { "shared read only space", "shared read write space", - "shared miscellaneous data space" + "shared miscellaneous data space", + "shared miscellaneous code space" }; static const char* flag[] = { "SharedReadOnlySize", "SharedReadWriteSize", - "SharedMiscDataSize" + "SharedMiscDataSize", + "SharedMiscCodeSize" }; warning("\nThe %s is not large enough\n" - "to preload requested classes. Use -XX:%s=\n" + "to preload requested classes. Use -XX:%s=\n" "to increase the initial size of %s.\n", name[shared_space], flag[shared_space], name[shared_space]); exit(2); diff --git a/hotspot/src/share/vm/utilities/debug.hpp b/hotspot/src/share/vm/utilities/debug.hpp index 51e516a5bb5..7995e6c085d 100644 --- a/hotspot/src/share/vm/utilities/debug.hpp +++ b/hotspot/src/share/vm/utilities/debug.hpp @@ -245,7 +245,8 @@ template <> struct StaticAssert {}; enum SharedSpaceType { SharedReadOnly, SharedReadWrite, - SharedMiscData + SharedMiscData, + SharedMiscCode }; void report_out_of_shared_space(SharedSpaceType space_type); diff --git a/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java b/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java index 6989a643f59..b2505be0d7d 100644 --- a/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java +++ b/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java @@ -51,9 +51,12 @@ public class LimitSharedSizes { // Known issue, JDK-8038422 (assert() on Windows) // new SharedSizeTestData("-XX:SharedMiscDataSize", "500k", "miscellaneous data"), - // This will cause a VM crash; commenting out for now; see bug JDK-8038268 - // @ignore JDK-8038268 - // new SharedSizeTestData("-XX:SharedMiscCodeSize", "20k", "miscellaneous code"), + // Too small of a misc code size should not cause a vm crash. + // It should result in the following error message: + // The shared miscellaneous code space is not large enough + // to preload requested classes. Use -XX:SharedMiscCodeSize= + // to increase the initial size of shared miscellaneous code space. + new SharedSizeTestData("-XX:SharedMiscCodeSize", "20k", "miscellaneous code"), // these values are larger than default ones, but should // be acceptable and not cause failure From 8f8d87ece5f2496305208a4b0c072de5cea0d810 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Thu, 23 Oct 2014 16:19:32 -0400 Subject: [PATCH 25/67] 8061748: Remove check_ct_logs_at_safepoint() Remove unused function and related closure class Reviewed-by: jwilhelm, mgerdin --- .../gc_implementation/g1/g1CollectedHeap.cpp | 77 ------------------- .../gc_implementation/g1/g1CollectedHeap.hpp | 3 - 2 files changed, 80 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 5d1ba94cc27..ebd77eb0b1e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -127,41 +127,6 @@ public: }; -class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { - size_t _num_processed; - CardTableModRefBS* _ctbs; - int _histo[256]; - - public: - ClearLoggedCardTableEntryClosure() : - _num_processed(0), _ctbs(G1CollectedHeap::heap()->g1_barrier_set()) - { - for (int i = 0; i < 256; i++) _histo[i] = 0; - } - - bool do_card_ptr(jbyte* card_ptr, uint worker_i) { - unsigned char* ujb = (unsigned char*)card_ptr; - int ind = (int)(*ujb); - _histo[ind]++; - - *card_ptr = (jbyte)CardTableModRefBS::clean_card_val(); - _num_processed++; - - return true; - } - - size_t num_processed() { return _num_processed; } - - void print_histo() { - gclog_or_tty->print_cr("Card table value histogram:"); - for (int i = 0; i < 256; i++) { - if (_histo[i] != 0) { - gclog_or_tty->print_cr(" %d: %d", i, _histo[i]); - } - } - } -}; - class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure { private: size_t _num_processed; @@ -475,48 +440,6 @@ bool G1CollectedHeap::is_scavengable(const void* p) { return !hr->is_humongous(); } -void G1CollectedHeap::check_ct_logs_at_safepoint() { - DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); - CardTableModRefBS* ct_bs = g1_barrier_set(); - - // Count the dirty cards at the start. - CountNonCleanMemRegionClosure count1(this); - ct_bs->mod_card_iterate(&count1); - int orig_count = count1.n(); - - // First clear the logged cards. - ClearLoggedCardTableEntryClosure clear; - dcqs.apply_closure_to_all_completed_buffers(&clear); - dcqs.iterate_closure_all_threads(&clear, false); - clear.print_histo(); - - // Now ensure that there's no dirty cards. - CountNonCleanMemRegionClosure count2(this); - ct_bs->mod_card_iterate(&count2); - if (count2.n() != 0) { - gclog_or_tty->print_cr("Card table has %d entries; %d originally", - count2.n(), orig_count); - } - guarantee(count2.n() == 0, "Card table should be clean."); - - RedirtyLoggedCardTableEntryClosure redirty; - dcqs.apply_closure_to_all_completed_buffers(&redirty); - dcqs.iterate_closure_all_threads(&redirty, false); - gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.", - clear.num_processed(), orig_count); - guarantee(redirty.num_processed() == clear.num_processed(), - err_msg("Redirtied "SIZE_FORMAT" cards, bug cleared "SIZE_FORMAT, - redirty.num_processed(), clear.num_processed())); - - CountNonCleanMemRegionClosure count3(this); - ct_bs->mod_card_iterate(&count3); - if (count3.n() != orig_count) { - gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.", - orig_count, count3.n()); - guarantee(count3.n() >= orig_count, "Should have restored them all."); - } -} - // Private class members. G1CollectedHeap* G1CollectedHeap::_g1h; diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 1307d4a6efd..f1aaceaacb4 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -797,9 +797,6 @@ protected: // The closure used to refine a single card. RefineCardTableEntryClosure* _refine_cte_cl; - // A function to check the consistency of dirty card logs. - void check_ct_logs_at_safepoint(); - // A DirtyCardQueueSet that is used to hold cards that contain // references into the current collection set. This is used to // update the remembered sets of the regions in the collection From 5306f2430a160a68fb8a24bdf5c437a9f4910479 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Thu, 23 Oct 2014 14:43:08 -0700 Subject: [PATCH 26/67] 6191224: (reflect) Misleading detail string in IllegalArgumentException thrown by Array.get The test case shows that an exception is thrown with the message "Argument is not an array", when in fact the argument is an array, but an array of a primitive type is actually what was expected. Fixed by differentiating between failing because an array was expected and failing because an array of a primitive type was expected. Reviewed-by: dholmes, ctornqvi, lfoltan --- hotspot/src/share/vm/prims/jvm.cpp | 4 +- .../runtime/reflect/ArrayGetIntException.java | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 hotspot/test/runtime/reflect/ArrayGetIntException.java diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index 98be942d9c7..ad58d7bf966 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -3271,8 +3271,10 @@ static inline arrayOop check_array(JNIEnv *env, jobject arr, bool type_array_onl THROW_0(vmSymbols::java_lang_NullPointerException()); } oop a = JNIHandles::resolve_non_null(arr); - if (!a->is_array() || (type_array_only && !a->is_typeArray())) { + if (!a->is_array()) { THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Argument is not an array"); + } else if (type_array_only && !a->is_typeArray()) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Argument is not an array of primitive type"); } return arrayOop(a); } diff --git a/hotspot/test/runtime/reflect/ArrayGetIntException.java b/hotspot/test/runtime/reflect/ArrayGetIntException.java new file mode 100644 index 00000000000..e5ee5cb93dc --- /dev/null +++ b/hotspot/test/runtime/reflect/ArrayGetIntException.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014, 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 6191224 + * @summary (reflect) Misleading detail string in IllegalArgumentException thrown by Array.get + * @run main ArrayGetIntException + */ +import java.io.*; +import java.lang.reflect.Array; + +public class ArrayGetIntException { + public static void main(String[] args) throws Exception { + Object[] objArray = {new Integer(Integer.MAX_VALUE)}; + + // this access is legal + try { + System.out.println(Array.get(objArray, 0)); + System.out.println("Test #1 PASSES"); + } catch(Exception e) { + failTest("Test #1 FAILS - legal access denied" + e.getMessage()); + } + + // this access is not legal, but needs to generate the proper exception message + try { + System.out.println(Array.getInt(objArray, 0)); + failTest("Test #2 FAILS - no exception"); + } catch(Exception e) { + System.out.println(e); + if (e.getMessage().equals("Argument is not an array of primitive type")) { + System.out.println("Test #2 PASSES"); + } else { + failTest("Test #2 FAILS - incorrect message: " + e.getMessage()); + } + } + + // this access is not legal, but needs to generate the proper exception message + try { + System.out.println(Array.getInt(new Object(), 0)); + failTest("Test #3 FAILS - no exception"); + } catch(Exception e) { + System.out.println(e); + if (e.getMessage().equals("Argument is not an array")) { + System.out.println("Test #3 PASSES"); + } else { + failTest("Test #3 FAILS - incorrect message: " + e.getMessage()); + } + } + } + + private static void failTest(String errStr) { + System.out.println(errStr); + throw new Error(errStr); + } +} From f5c3ac04e425804e8e0a51c815dbdf9ec8d19e7e Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Fri, 24 Oct 2014 08:56:47 -0400 Subject: [PATCH 27/67] 8061962: classFileParser.cpp.orig got erroneously added to the hotspot source repository Remove the file Reviewed-by: coleenp, ccheung --- .../vm/classfile/classFileParser.cpp.orig | 5274 ----------------- 1 file changed, 5274 deletions(-) delete mode 100644 hotspot/src/share/vm/classfile/classFileParser.cpp.orig diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp.orig b/hotspot/src/share/vm/classfile/classFileParser.cpp.orig deleted file mode 100644 index 0f2f8d590c4..00000000000 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp.orig +++ /dev/null @@ -1,5274 +0,0 @@ -/* - * Copyright (c) 1997, 2014, 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 "precompiled.hpp" -#include "classfile/classFileParser.hpp" -#include "classfile/classLoader.hpp" -#include "classfile/classLoaderData.hpp" -#include "classfile/classLoaderData.inline.hpp" -#include "classfile/defaultMethods.hpp" -#include "classfile/javaClasses.hpp" -#include "classfile/symbolTable.hpp" -#include "classfile/systemDictionary.hpp" -#if INCLUDE_CDS -#include "classfile/systemDictionaryShared.hpp" -#endif -#include "classfile/verificationType.hpp" -#include "classfile/verifier.hpp" -#include "classfile/vmSymbols.hpp" -#include "memory/allocation.hpp" -#include "memory/gcLocker.hpp" -#include "memory/metadataFactory.hpp" -#include "memory/oopFactory.hpp" -#include "memory/referenceType.hpp" -#include "memory/universe.inline.hpp" -#include "oops/constantPool.hpp" -#include "oops/fieldStreams.hpp" -#include "oops/instanceKlass.hpp" -#include "oops/instanceMirrorKlass.hpp" -#include "oops/klass.inline.hpp" -#include "oops/klassVtable.hpp" -#include "oops/method.hpp" -#include "oops/symbol.hpp" -#include "prims/jvm.h" -#include "prims/jvmtiExport.hpp" -#include "prims/jvmtiThreadState.hpp" -#include "runtime/javaCalls.hpp" -#include "runtime/perfData.hpp" -#include "runtime/reflection.hpp" -#include "runtime/signature.hpp" -#include "runtime/timer.hpp" -#include "services/classLoadingService.hpp" -#include "services/threadService.hpp" -#include "utilities/array.hpp" -#include "utilities/globalDefinitions.hpp" -#include "utilities/ostream.hpp" - -// We generally try to create the oops directly when parsing, rather than -// allocating temporary data structures and copying the bytes twice. A -// temporary area is only needed when parsing utf8 entries in the constant -// pool and when parsing line number tables. - -// We add assert in debug mode when class format is not checked. - -#define JAVA_CLASSFILE_MAGIC 0xCAFEBABE -#define JAVA_MIN_SUPPORTED_VERSION 45 -#define JAVA_MAX_SUPPORTED_VERSION 52 -#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0 - -// Used for two backward compatibility reasons: -// - to check for new additions to the class file format in JDK1.5 -// - to check for bug fixes in the format checker in JDK1.5 -#define JAVA_1_5_VERSION 49 - -// Used for backward compatibility reasons: -// - to check for javac bug fixes that happened after 1.5 -// - also used as the max version when running in jdk6 -#define JAVA_6_VERSION 50 - -// Used for backward compatibility reasons: -// - to check NameAndType_info signatures more aggressively -#define JAVA_7_VERSION 51 - -// Extension method support. -#define JAVA_8_VERSION 52 - -void ClassFileParser::parse_constant_pool_entries(int length, TRAPS) { - // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize - // this function (_current can be allocated in a register, with scalar - // replacement of aggregates). The _current pointer is copied back to - // stream() when this function returns. DON'T call another method within - // this method that uses stream(). - ClassFileStream* cfs0 = stream(); - ClassFileStream cfs1 = *cfs0; - ClassFileStream* cfs = &cfs1; -#ifdef ASSERT - assert(cfs->allocated_on_stack(),"should be local"); - u1* old_current = cfs0->current(); -#endif - Handle class_loader(THREAD, _loader_data->class_loader()); - - // Used for batching symbol allocations. - const char* names[SymbolTable::symbol_alloc_batch_size]; - int lengths[SymbolTable::symbol_alloc_batch_size]; - int indices[SymbolTable::symbol_alloc_batch_size]; - unsigned int hashValues[SymbolTable::symbol_alloc_batch_size]; - int names_count = 0; - - // parsing Index 0 is unused - for (int index = 1; index < length; index++) { - // Each of the following case guarantees one more byte in the stream - // for the following tag or the access_flags following constant pool, - // so we don't need bounds-check for reading tag. - u1 tag = cfs->get_u1_fast(); - switch (tag) { - case JVM_CONSTANT_Class : - { - cfs->guarantee_more(3, CHECK); // name_index, tag/access_flags - u2 name_index = cfs->get_u2_fast(); - _cp->klass_index_at_put(index, name_index); - } - break; - case JVM_CONSTANT_Fieldref : - { - cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags - u2 class_index = cfs->get_u2_fast(); - u2 name_and_type_index = cfs->get_u2_fast(); - _cp->field_at_put(index, class_index, name_and_type_index); - } - break; - case JVM_CONSTANT_Methodref : - { - cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags - u2 class_index = cfs->get_u2_fast(); - u2 name_and_type_index = cfs->get_u2_fast(); - _cp->method_at_put(index, class_index, name_and_type_index); - } - break; - case JVM_CONSTANT_InterfaceMethodref : - { - cfs->guarantee_more(5, CHECK); // class_index, name_and_type_index, tag/access_flags - u2 class_index = cfs->get_u2_fast(); - u2 name_and_type_index = cfs->get_u2_fast(); - _cp->interface_method_at_put(index, class_index, name_and_type_index); - } - break; - case JVM_CONSTANT_String : - { - cfs->guarantee_more(3, CHECK); // string_index, tag/access_flags - u2 string_index = cfs->get_u2_fast(); - _cp->string_index_at_put(index, string_index); - } - break; - case JVM_CONSTANT_MethodHandle : - case JVM_CONSTANT_MethodType : - if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { - classfile_parse_error( - "Class file version does not support constant tag %u in class file %s", - tag, CHECK); - } - if (tag == JVM_CONSTANT_MethodHandle) { - cfs->guarantee_more(4, CHECK); // ref_kind, method_index, tag/access_flags - u1 ref_kind = cfs->get_u1_fast(); - u2 method_index = cfs->get_u2_fast(); - _cp->method_handle_index_at_put(index, ref_kind, method_index); - } else if (tag == JVM_CONSTANT_MethodType) { - cfs->guarantee_more(3, CHECK); // signature_index, tag/access_flags - u2 signature_index = cfs->get_u2_fast(); - _cp->method_type_index_at_put(index, signature_index); - } else { - ShouldNotReachHere(); - } - break; - case JVM_CONSTANT_InvokeDynamic : - { - if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { - classfile_parse_error( - "Class file version does not support constant tag %u in class file %s", - tag, CHECK); - } - cfs->guarantee_more(5, CHECK); // bsm_index, nt, tag/access_flags - u2 bootstrap_specifier_index = cfs->get_u2_fast(); - u2 name_and_type_index = cfs->get_u2_fast(); - if (_max_bootstrap_specifier_index < (int) bootstrap_specifier_index) - _max_bootstrap_specifier_index = (int) bootstrap_specifier_index; // collect for later - _cp->invoke_dynamic_at_put(index, bootstrap_specifier_index, name_and_type_index); - } - break; - case JVM_CONSTANT_Integer : - { - cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags - u4 bytes = cfs->get_u4_fast(); - _cp->int_at_put(index, (jint) bytes); - } - break; - case JVM_CONSTANT_Float : - { - cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags - u4 bytes = cfs->get_u4_fast(); - _cp->float_at_put(index, *(jfloat*)&bytes); - } - break; - case JVM_CONSTANT_Long : - // A mangled type might cause you to overrun allocated memory - guarantee_property(index+1 < length, - "Invalid constant pool entry %u in class file %s", - index, CHECK); - { - cfs->guarantee_more(9, CHECK); // bytes, tag/access_flags - u8 bytes = cfs->get_u8_fast(); - _cp->long_at_put(index, bytes); - } - index++; // Skip entry following eigth-byte constant, see JVM book p. 98 - break; - case JVM_CONSTANT_Double : - // A mangled type might cause you to overrun allocated memory - guarantee_property(index+1 < length, - "Invalid constant pool entry %u in class file %s", - index, CHECK); - { - cfs->guarantee_more(9, CHECK); // bytes, tag/access_flags - u8 bytes = cfs->get_u8_fast(); - _cp->double_at_put(index, *(jdouble*)&bytes); - } - index++; // Skip entry following eigth-byte constant, see JVM book p. 98 - break; - case JVM_CONSTANT_NameAndType : - { - cfs->guarantee_more(5, CHECK); // name_index, signature_index, tag/access_flags - u2 name_index = cfs->get_u2_fast(); - u2 signature_index = cfs->get_u2_fast(); - _cp->name_and_type_at_put(index, name_index, signature_index); - } - break; - case JVM_CONSTANT_Utf8 : - { - cfs->guarantee_more(2, CHECK); // utf8_length - u2 utf8_length = cfs->get_u2_fast(); - u1* utf8_buffer = cfs->get_u1_buffer(); - assert(utf8_buffer != NULL, "null utf8 buffer"); - // Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward. - cfs->guarantee_more(utf8_length+1, CHECK); // utf8 string, tag/access_flags - cfs->skip_u1_fast(utf8_length); - - // Before storing the symbol, make sure it's legal - if (_need_verify) { - verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK); - } - - if (has_cp_patch_at(index)) { - Handle patch = clear_cp_patch_at(index); - guarantee_property(java_lang_String::is_instance(patch()), - "Illegal utf8 patch at %d in class file %s", - index, CHECK); - char* str = java_lang_String::as_utf8_string(patch()); - // (could use java_lang_String::as_symbol instead, but might as well batch them) - utf8_buffer = (u1*) str; - utf8_length = (int) strlen(str); - } - - unsigned int hash; - Symbol* result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash); - if (result == NULL) { - names[names_count] = (char*)utf8_buffer; - lengths[names_count] = utf8_length; - indices[names_count] = index; - hashValues[names_count++] = hash; - if (names_count == SymbolTable::symbol_alloc_batch_size) { - SymbolTable::new_symbols(_loader_data, _cp, names_count, names, lengths, indices, hashValues, CHECK); - names_count = 0; - } - } else { - _cp->symbol_at_put(index, result); - } - } - break; - default: - classfile_parse_error( - "Unknown constant tag %u in class file %s", tag, CHECK); - break; - } - } - - // Allocate the remaining symbols - if (names_count > 0) { - SymbolTable::new_symbols(_loader_data, _cp, names_count, names, lengths, indices, hashValues, CHECK); - } - - // Copy _current pointer of local copy back to stream(). -#ifdef ASSERT - assert(cfs0->current() == old_current, "non-exclusive use of stream()"); -#endif - cfs0->set_current(cfs1.current()); -} - -bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); } - -inline Symbol* check_symbol_at(constantPoolHandle cp, int index) { - if (valid_cp_range(index, cp->length()) && cp->tag_at(index).is_utf8()) - return cp->symbol_at(index); - else - return NULL; -} - -constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) { - ClassFileStream* cfs = stream(); - constantPoolHandle nullHandle; - - cfs->guarantee_more(3, CHECK_(nullHandle)); // length, first cp tag - u2 length = cfs->get_u2_fast(); - guarantee_property( - length >= 1, "Illegal constant pool size %u in class file %s", - length, CHECK_(nullHandle)); - ConstantPool* constant_pool = ConstantPool::allocate(_loader_data, length, - CHECK_(nullHandle)); - _cp = constant_pool; // save in case of errors - constantPoolHandle cp (THREAD, constant_pool); - - // parsing constant pool entries - parse_constant_pool_entries(length, CHECK_(nullHandle)); - - int index = 1; // declared outside of loops for portability - - // first verification pass - validate cross references and fixup class and string constants - for (index = 1; index < length; index++) { // Index 0 is unused - jbyte tag = cp->tag_at(index).value(); - switch (tag) { - case JVM_CONSTANT_Class : - ShouldNotReachHere(); // Only JVM_CONSTANT_ClassIndex should be present - break; - case JVM_CONSTANT_Fieldref : - // fall through - case JVM_CONSTANT_Methodref : - // fall through - case JVM_CONSTANT_InterfaceMethodref : { - if (!_need_verify) break; - int klass_ref_index = cp->klass_ref_index_at(index); - int name_and_type_ref_index = cp->name_and_type_ref_index_at(index); - check_property(valid_klass_reference_at(klass_ref_index), - "Invalid constant pool index %u in class file %s", - klass_ref_index, - CHECK_(nullHandle)); - check_property(valid_cp_range(name_and_type_ref_index, length) && - cp->tag_at(name_and_type_ref_index).is_name_and_type(), - "Invalid constant pool index %u in class file %s", - name_and_type_ref_index, - CHECK_(nullHandle)); - break; - } - case JVM_CONSTANT_String : - ShouldNotReachHere(); // Only JVM_CONSTANT_StringIndex should be present - break; - case JVM_CONSTANT_Integer : - break; - case JVM_CONSTANT_Float : - break; - case JVM_CONSTANT_Long : - case JVM_CONSTANT_Double : - index++; - check_property( - (index < length && cp->tag_at(index).is_invalid()), - "Improper constant pool long/double index %u in class file %s", - index, CHECK_(nullHandle)); - break; - case JVM_CONSTANT_NameAndType : { - if (!_need_verify) break; - int name_ref_index = cp->name_ref_index_at(index); - int signature_ref_index = cp->signature_ref_index_at(index); - check_property(valid_symbol_at(name_ref_index), - "Invalid constant pool index %u in class file %s", - name_ref_index, CHECK_(nullHandle)); - check_property(valid_symbol_at(signature_ref_index), - "Invalid constant pool index %u in class file %s", - signature_ref_index, CHECK_(nullHandle)); - break; - } - case JVM_CONSTANT_Utf8 : - break; - case JVM_CONSTANT_UnresolvedClass : // fall-through - case JVM_CONSTANT_UnresolvedClassInError: - ShouldNotReachHere(); // Only JVM_CONSTANT_ClassIndex should be present - break; - case JVM_CONSTANT_ClassIndex : - { - int class_index = cp->klass_index_at(index); - check_property(valid_symbol_at(class_index), - "Invalid constant pool index %u in class file %s", - class_index, CHECK_(nullHandle)); - cp->unresolved_klass_at_put(index, cp->symbol_at(class_index)); - } - break; - case JVM_CONSTANT_StringIndex : - { - int string_index = cp->string_index_at(index); - check_property(valid_symbol_at(string_index), - "Invalid constant pool index %u in class file %s", - string_index, CHECK_(nullHandle)); - Symbol* sym = cp->symbol_at(string_index); - cp->unresolved_string_at_put(index, sym); - } - break; - case JVM_CONSTANT_MethodHandle : - { - int ref_index = cp->method_handle_index_at(index); - check_property( - valid_cp_range(ref_index, length), - "Invalid constant pool index %u in class file %s", - ref_index, CHECK_(nullHandle)); - constantTag tag = cp->tag_at(ref_index); - int ref_kind = cp->method_handle_ref_kind_at(index); - switch (ref_kind) { - case JVM_REF_getField: - case JVM_REF_getStatic: - case JVM_REF_putField: - case JVM_REF_putStatic: - check_property( - tag.is_field(), - "Invalid constant pool index %u in class file %s (not a field)", - ref_index, CHECK_(nullHandle)); - break; - case JVM_REF_invokeVirtual: - case JVM_REF_newInvokeSpecial: - check_property( - tag.is_method(), - "Invalid constant pool index %u in class file %s (not a method)", - ref_index, CHECK_(nullHandle)); - break; - case JVM_REF_invokeStatic: - case JVM_REF_invokeSpecial: - check_property(tag.is_method() || - ((_major_version >= JAVA_8_VERSION) && tag.is_interface_method()), - "Invalid constant pool index %u in class file %s (not a method)", - ref_index, CHECK_(nullHandle)); - break; - case JVM_REF_invokeInterface: - check_property( - tag.is_interface_method(), - "Invalid constant pool index %u in class file %s (not an interface method)", - ref_index, CHECK_(nullHandle)); - break; - default: - classfile_parse_error( - "Bad method handle kind at constant pool index %u in class file %s", - index, CHECK_(nullHandle)); - } - // Keep the ref_index unchanged. It will be indirected at link-time. - } - break; - case JVM_CONSTANT_MethodType : - { - int ref_index = cp->method_type_index_at(index); - check_property(valid_symbol_at(ref_index), - "Invalid constant pool index %u in class file %s", - ref_index, CHECK_(nullHandle)); - } - break; - case JVM_CONSTANT_InvokeDynamic : - { - int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index); - check_property(valid_cp_range(name_and_type_ref_index, length) && - cp->tag_at(name_and_type_ref_index).is_name_and_type(), - "Invalid constant pool index %u in class file %s", - name_and_type_ref_index, - CHECK_(nullHandle)); - // bootstrap specifier index must be checked later, when BootstrapMethods attr is available - break; - } - default: - fatal(err_msg("bad constant pool tag value %u", - cp->tag_at(index).value())); - ShouldNotReachHere(); - break; - } // end of switch - } // end of for - - if (_cp_patches != NULL) { - // need to treat this_class specially... - int this_class_index; - { - cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len - u1* mark = cfs->current(); - u2 flags = cfs->get_u2_fast(); - this_class_index = cfs->get_u2_fast(); - cfs->set_current(mark); // revert to mark - } - - for (index = 1; index < length; index++) { // Index 0 is unused - if (has_cp_patch_at(index)) { - guarantee_property(index != this_class_index, - "Illegal constant pool patch to self at %d in class file %s", - index, CHECK_(nullHandle)); - patch_constant_pool(cp, index, cp_patch_at(index), CHECK_(nullHandle)); - } - } - } - - if (!_need_verify) { - return cp; - } - - // second verification pass - checks the strings are of the right format. - // but not yet to the other entries - for (index = 1; index < length; index++) { - jbyte tag = cp->tag_at(index).value(); - switch (tag) { - case JVM_CONSTANT_UnresolvedClass: { - Symbol* class_name = cp->klass_name_at(index); - // check the name, even if _cp_patches will overwrite it - verify_legal_class_name(class_name, CHECK_(nullHandle)); - break; - } - case JVM_CONSTANT_NameAndType: { - if (_need_verify && _major_version >= JAVA_7_VERSION) { - int sig_index = cp->signature_ref_index_at(index); - int name_index = cp->name_ref_index_at(index); - Symbol* name = cp->symbol_at(name_index); - Symbol* sig = cp->symbol_at(sig_index); - if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) { - verify_legal_method_signature(name, sig, CHECK_(nullHandle)); - } else { - verify_legal_field_signature(name, sig, CHECK_(nullHandle)); - } - } - break; - } - case JVM_CONSTANT_InvokeDynamic: - case JVM_CONSTANT_Fieldref: - case JVM_CONSTANT_Methodref: - case JVM_CONSTANT_InterfaceMethodref: { - int name_and_type_ref_index = cp->name_and_type_ref_index_at(index); - // already verified to be utf8 - int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index); - // already verified to be utf8 - int signature_ref_index = cp->signature_ref_index_at(name_and_type_ref_index); - Symbol* name = cp->symbol_at(name_ref_index); - Symbol* signature = cp->symbol_at(signature_ref_index); - if (tag == JVM_CONSTANT_Fieldref) { - verify_legal_field_name(name, CHECK_(nullHandle)); - if (_need_verify && _major_version >= JAVA_7_VERSION) { - // Signature is verified above, when iterating NameAndType_info. - // Need only to be sure it's the right type. - if (signature->byte_at(0) == JVM_SIGNATURE_FUNC) { - throwIllegalSignature( - "Field", name, signature, CHECK_(nullHandle)); - } - } else { - verify_legal_field_signature(name, signature, CHECK_(nullHandle)); - } - } else { - verify_legal_method_name(name, CHECK_(nullHandle)); - if (_need_verify && _major_version >= JAVA_7_VERSION) { - // Signature is verified above, when iterating NameAndType_info. - // Need only to be sure it's the right type. - if (signature->byte_at(0) != JVM_SIGNATURE_FUNC) { - throwIllegalSignature( - "Method", name, signature, CHECK_(nullHandle)); - } - } else { - verify_legal_method_signature(name, signature, CHECK_(nullHandle)); - } - if (tag == JVM_CONSTANT_Methodref) { - // 4509014: If a class method name begins with '<', it must be "". - assert(name != NULL, "method name in constant pool is null"); - unsigned int name_len = name->utf8_length(); - assert(name_len > 0, "bad method name"); // already verified as legal name - if (name->byte_at(0) == '<') { - if (name != vmSymbols::object_initializer_name()) { - classfile_parse_error( - "Bad method name at constant pool index %u in class file %s", - name_ref_index, CHECK_(nullHandle)); - } - } - } - } - break; - } - case JVM_CONSTANT_MethodHandle: { - int ref_index = cp->method_handle_index_at(index); - int ref_kind = cp->method_handle_ref_kind_at(index); - switch (ref_kind) { - case JVM_REF_invokeVirtual: - case JVM_REF_invokeStatic: - case JVM_REF_invokeSpecial: - case JVM_REF_newInvokeSpecial: - { - int name_and_type_ref_index = cp->name_and_type_ref_index_at(ref_index); - int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index); - Symbol* name = cp->symbol_at(name_ref_index); - if (ref_kind == JVM_REF_newInvokeSpecial) { - if (name != vmSymbols::object_initializer_name()) { - classfile_parse_error( - "Bad constructor name at constant pool index %u in class file %s", - name_ref_index, CHECK_(nullHandle)); - } - } else { - if (name == vmSymbols::object_initializer_name()) { - classfile_parse_error( - "Bad method name at constant pool index %u in class file %s", - name_ref_index, CHECK_(nullHandle)); - } - } - } - break; - // Other ref_kinds are already fully checked in previous pass. - } - break; - } - case JVM_CONSTANT_MethodType: { - Symbol* no_name = vmSymbols::type_name(); // place holder - Symbol* signature = cp->method_type_signature_at(index); - verify_legal_method_signature(no_name, signature, CHECK_(nullHandle)); - break; - } - case JVM_CONSTANT_Utf8: { - assert(cp->symbol_at(index)->refcount() != 0, "count corrupted"); - } - } // end of switch - } // end of for - - return cp; -} - - -void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) { - BasicType patch_type = T_VOID; - - switch (cp->tag_at(index).value()) { - - case JVM_CONSTANT_UnresolvedClass : - // Patching a class means pre-resolving it. - // The name in the constant pool is ignored. - if (java_lang_Class::is_instance(patch())) { - guarantee_property(!java_lang_Class::is_primitive(patch()), - "Illegal class patch at %d in class file %s", - index, CHECK); - cp->klass_at_put(index, java_lang_Class::as_Klass(patch())); - } else { - guarantee_property(java_lang_String::is_instance(patch()), - "Illegal class patch at %d in class file %s", - index, CHECK); - Symbol* name = java_lang_String::as_symbol(patch(), CHECK); - cp->unresolved_klass_at_put(index, name); - } - break; - - case JVM_CONSTANT_String : - // skip this patch and don't clear it. Needs the oop array for resolved - // references to be created first. - return; - - case JVM_CONSTANT_Integer : patch_type = T_INT; goto patch_prim; - case JVM_CONSTANT_Float : patch_type = T_FLOAT; goto patch_prim; - case JVM_CONSTANT_Long : patch_type = T_LONG; goto patch_prim; - case JVM_CONSTANT_Double : patch_type = T_DOUBLE; goto patch_prim; - patch_prim: - { - jvalue value; - BasicType value_type = java_lang_boxing_object::get_value(patch(), &value); - guarantee_property(value_type == patch_type, - "Illegal primitive patch at %d in class file %s", - index, CHECK); - switch (value_type) { - case T_INT: cp->int_at_put(index, value.i); break; - case T_FLOAT: cp->float_at_put(index, value.f); break; - case T_LONG: cp->long_at_put(index, value.j); break; - case T_DOUBLE: cp->double_at_put(index, value.d); break; - default: assert(false, ""); - } - } - break; - - default: - // %%% TODO: put method handles into CONSTANT_InterfaceMethodref, etc. - guarantee_property(!has_cp_patch_at(index), - "Illegal unexpected patch at %d in class file %s", - index, CHECK); - return; - } - - // On fall-through, mark the patch as used. - clear_cp_patch_at(index); -} - - - -class NameSigHash: public ResourceObj { - public: - Symbol* _name; // name - Symbol* _sig; // signature - NameSigHash* _next; // Next entry in hash table -}; - - -#define HASH_ROW_SIZE 256 - -unsigned int hash(Symbol* name, Symbol* sig) { - unsigned int raw_hash = 0; - raw_hash += ((unsigned int)(uintptr_t)name) >> (LogHeapWordSize + 2); - raw_hash += ((unsigned int)(uintptr_t)sig) >> LogHeapWordSize; - - return (raw_hash + (unsigned int)(uintptr_t)name) % HASH_ROW_SIZE; -} - - -void initialize_hashtable(NameSigHash** table) { - memset((void*)table, 0, sizeof(NameSigHash*) * HASH_ROW_SIZE); -} - -// Return false if the name/sig combination is found in table. -// Return true if no duplicate is found. And name/sig is added as a new entry in table. -// The old format checker uses heap sort to find duplicates. -// NOTE: caller should guarantee that GC doesn't happen during the life cycle -// of table since we don't expect Symbol*'s to move. -bool put_after_lookup(Symbol* name, Symbol* sig, NameSigHash** table) { - assert(name != NULL, "name in constant pool is NULL"); - - // First lookup for duplicates - int index = hash(name, sig); - NameSigHash* entry = table[index]; - while (entry != NULL) { - if (entry->_name == name && entry->_sig == sig) { - return false; - } - entry = entry->_next; - } - - // No duplicate is found, allocate a new entry and fill it. - entry = new NameSigHash(); - entry->_name = name; - entry->_sig = sig; - - // Insert into hash table - entry->_next = table[index]; - table[index] = entry; - - return true; -} - - -Array* ClassFileParser::parse_interfaces(int length, - Handle protection_domain, - Symbol* class_name, - bool* has_default_methods, - TRAPS) { - if (length == 0) { - _local_interfaces = Universe::the_empty_klass_array(); - } else { - ClassFileStream* cfs = stream(); - assert(length > 0, "only called for length>0"); - _local_interfaces = MetadataFactory::new_array(_loader_data, length, NULL, CHECK_NULL); - - int index; - for (index = 0; index < length; index++) { - u2 interface_index = cfs->get_u2(CHECK_NULL); - KlassHandle interf; - check_property( - valid_klass_reference_at(interface_index), - "Interface name has bad constant pool index %u in class file %s", - interface_index, CHECK_NULL); - if (_cp->tag_at(interface_index).is_klass()) { - interf = KlassHandle(THREAD, _cp->resolved_klass_at(interface_index)); - } else { - Symbol* unresolved_klass = _cp->klass_name_at(interface_index); - - // Don't need to check legal name because it's checked when parsing constant pool. - // But need to make sure it's not an array type. - guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY, - "Bad interface name in class file %s", CHECK_NULL); - Handle class_loader(THREAD, _loader_data->class_loader()); - - // Call resolve_super so classcircularity is checked - Klass* k = SystemDictionary::resolve_super_or_fail(class_name, - unresolved_klass, class_loader, protection_domain, - false, CHECK_NULL); - interf = KlassHandle(THREAD, k); - } - - if (!interf()->is_interface()) { - THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", NULL); - } - if (InstanceKlass::cast(interf())->has_default_methods()) { - *has_default_methods = true; - } - _local_interfaces->at_put(index, interf()); - } - - if (!_need_verify || length <= 1) { - return _local_interfaces; - } - - // Check if there's any duplicates in interfaces - ResourceMark rm(THREAD); - NameSigHash** interface_names = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, NameSigHash*, HASH_ROW_SIZE); - initialize_hashtable(interface_names); - bool dup = false; - { - debug_only(No_Safepoint_Verifier nsv;) - for (index = 0; index < length; index++) { - Klass* k = _local_interfaces->at(index); - Symbol* name = InstanceKlass::cast(k)->name(); - // If no duplicates, add (name, NULL) in hashtable interface_names. - if (!put_after_lookup(name, NULL, interface_names)) { - dup = true; - break; - } - } - } - if (dup) { - classfile_parse_error("Duplicate interface name in class file %s", CHECK_NULL); - } - } - return _local_interfaces; -} - - -void ClassFileParser::verify_constantvalue(int constantvalue_index, int signature_index, TRAPS) { - // Make sure the constant pool entry is of a type appropriate to this field - guarantee_property( - (constantvalue_index > 0 && - constantvalue_index < _cp->length()), - "Bad initial value index %u in ConstantValue attribute in class file %s", - constantvalue_index, CHECK); - constantTag value_type = _cp->tag_at(constantvalue_index); - switch ( _cp->basic_type_for_signature_at(signature_index) ) { - case T_LONG: - guarantee_property(value_type.is_long(), "Inconsistent constant value type in class file %s", CHECK); - break; - case T_FLOAT: - guarantee_property(value_type.is_float(), "Inconsistent constant value type in class file %s", CHECK); - break; - case T_DOUBLE: - guarantee_property(value_type.is_double(), "Inconsistent constant value type in class file %s", CHECK); - break; - case T_BYTE: case T_CHAR: case T_SHORT: case T_BOOLEAN: case T_INT: - guarantee_property(value_type.is_int(), "Inconsistent constant value type in class file %s", CHECK); - break; - case T_OBJECT: - guarantee_property((_cp->symbol_at(signature_index)->equals("Ljava/lang/String;") - && value_type.is_string()), - "Bad string initial value in class file %s", CHECK); - break; - default: - classfile_parse_error( - "Unable to set initial value %u in class file %s", - constantvalue_index, CHECK); - } -} - - -// Parse attributes for a field. -void ClassFileParser::parse_field_attributes(u2 attributes_count, - bool is_static, u2 signature_index, - u2* constantvalue_index_addr, - bool* is_synthetic_addr, - u2* generic_signature_index_addr, - ClassFileParser::FieldAnnotationCollector* parsed_annotations, - TRAPS) { - ClassFileStream* cfs = stream(); - assert(attributes_count > 0, "length should be greater than 0"); - u2 constantvalue_index = 0; - u2 generic_signature_index = 0; - bool is_synthetic = false; - u1* runtime_visible_annotations = NULL; - int runtime_visible_annotations_length = 0; - u1* runtime_invisible_annotations = NULL; - int runtime_invisible_annotations_length = 0; - u1* runtime_visible_type_annotations = NULL; - int runtime_visible_type_annotations_length = 0; - u1* runtime_invisible_type_annotations = NULL; - int runtime_invisible_type_annotations_length = 0; - bool runtime_invisible_annotations_exists = false; - bool runtime_invisible_type_annotations_exists = false; - while (attributes_count--) { - cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length - u2 attribute_name_index = cfs->get_u2_fast(); - u4 attribute_length = cfs->get_u4_fast(); - check_property(valid_symbol_at(attribute_name_index), - "Invalid field attribute index %u in class file %s", - attribute_name_index, - CHECK); - Symbol* attribute_name = _cp->symbol_at(attribute_name_index); - if (is_static && attribute_name == vmSymbols::tag_constant_value()) { - // ignore if non-static - if (constantvalue_index != 0) { - classfile_parse_error("Duplicate ConstantValue attribute in class file %s", CHECK); - } - check_property( - attribute_length == 2, - "Invalid ConstantValue field attribute length %u in class file %s", - attribute_length, CHECK); - constantvalue_index = cfs->get_u2(CHECK); - if (_need_verify) { - verify_constantvalue(constantvalue_index, signature_index, CHECK); - } - } else if (attribute_name == vmSymbols::tag_synthetic()) { - if (attribute_length != 0) { - classfile_parse_error( - "Invalid Synthetic field attribute length %u in class file %s", - attribute_length, CHECK); - } - is_synthetic = true; - } else if (attribute_name == vmSymbols::tag_deprecated()) { // 4276120 - if (attribute_length != 0) { - classfile_parse_error( - "Invalid Deprecated field attribute length %u in class file %s", - attribute_length, CHECK); - } - } else if (_major_version >= JAVA_1_5_VERSION) { - if (attribute_name == vmSymbols::tag_signature()) { - if (attribute_length != 2) { - classfile_parse_error( - "Wrong size %u for field's Signature attribute in class file %s", - attribute_length, CHECK); - } - generic_signature_index = parse_generic_signature_attribute(CHECK); - } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) { - if (runtime_visible_annotations != NULL) { - classfile_parse_error( - "Multiple RuntimeVisibleAnnotations attributes for field in class file %s", CHECK); - } - runtime_visible_annotations_length = attribute_length; - runtime_visible_annotations = cfs->get_u1_buffer(); - assert(runtime_visible_annotations != NULL, "null visible annotations"); - parse_annotations(runtime_visible_annotations, - runtime_visible_annotations_length, - parsed_annotations, - CHECK); - cfs->skip_u1(runtime_visible_annotations_length, CHECK); - } else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { - if (runtime_invisible_annotations_exists) { - classfile_parse_error( - "Multiple RuntimeInvisibleAnnotations attributes for field in class file %s", CHECK); - } - runtime_invisible_annotations_exists = true; - if (PreserveAllAnnotations) { - runtime_invisible_annotations_length = attribute_length; - runtime_invisible_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_annotations != NULL, "null invisible annotations"); - } - cfs->skip_u1(attribute_length, CHECK); - } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { - if (runtime_visible_type_annotations != NULL) { - classfile_parse_error( - "Multiple RuntimeVisibleTypeAnnotations attributes for field in class file %s", CHECK); - } - runtime_visible_type_annotations_length = attribute_length; - runtime_visible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); - cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); - } else if (attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { - if (runtime_invisible_type_annotations_exists) { - classfile_parse_error( - "Multiple RuntimeInvisibleTypeAnnotations attributes for field in class file %s", CHECK); - } else { - runtime_invisible_type_annotations_exists = true; - } - if (PreserveAllAnnotations) { - runtime_invisible_type_annotations_length = attribute_length; - runtime_invisible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); - } - cfs->skip_u1(attribute_length, CHECK); - } else { - cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes - } - } else { - cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes - } - } - - *constantvalue_index_addr = constantvalue_index; - *is_synthetic_addr = is_synthetic; - *generic_signature_index_addr = generic_signature_index; - AnnotationArray* a = assemble_annotations(runtime_visible_annotations, - runtime_visible_annotations_length, - runtime_invisible_annotations, - runtime_invisible_annotations_length, - CHECK); - parsed_annotations->set_field_annotations(a); - a = assemble_annotations(runtime_visible_type_annotations, - runtime_visible_type_annotations_length, - runtime_invisible_type_annotations, - runtime_invisible_type_annotations_length, - CHECK); - parsed_annotations->set_field_type_annotations(a); - return; -} - - -// Field allocation types. Used for computing field offsets. - -enum FieldAllocationType { - STATIC_OOP, // Oops - STATIC_BYTE, // Boolean, Byte, char - STATIC_SHORT, // shorts - STATIC_WORD, // ints - STATIC_DOUBLE, // aligned long or double - NONSTATIC_OOP, - NONSTATIC_BYTE, - NONSTATIC_SHORT, - NONSTATIC_WORD, - NONSTATIC_DOUBLE, - MAX_FIELD_ALLOCATION_TYPE, - BAD_ALLOCATION_TYPE = -1 -}; - -static FieldAllocationType _basic_type_to_atype[2 * (T_CONFLICT + 1)] = { - BAD_ALLOCATION_TYPE, // 0 - BAD_ALLOCATION_TYPE, // 1 - BAD_ALLOCATION_TYPE, // 2 - BAD_ALLOCATION_TYPE, // 3 - NONSTATIC_BYTE , // T_BOOLEAN = 4, - NONSTATIC_SHORT, // T_CHAR = 5, - NONSTATIC_WORD, // T_FLOAT = 6, - NONSTATIC_DOUBLE, // T_DOUBLE = 7, - NONSTATIC_BYTE, // T_BYTE = 8, - NONSTATIC_SHORT, // T_SHORT = 9, - NONSTATIC_WORD, // T_INT = 10, - NONSTATIC_DOUBLE, // T_LONG = 11, - NONSTATIC_OOP, // T_OBJECT = 12, - NONSTATIC_OOP, // T_ARRAY = 13, - BAD_ALLOCATION_TYPE, // T_VOID = 14, - BAD_ALLOCATION_TYPE, // T_ADDRESS = 15, - BAD_ALLOCATION_TYPE, // T_NARROWOOP = 16, - BAD_ALLOCATION_TYPE, // T_METADATA = 17, - BAD_ALLOCATION_TYPE, // T_NARROWKLASS = 18, - BAD_ALLOCATION_TYPE, // T_CONFLICT = 19, - BAD_ALLOCATION_TYPE, // 0 - BAD_ALLOCATION_TYPE, // 1 - BAD_ALLOCATION_TYPE, // 2 - BAD_ALLOCATION_TYPE, // 3 - STATIC_BYTE , // T_BOOLEAN = 4, - STATIC_SHORT, // T_CHAR = 5, - STATIC_WORD, // T_FLOAT = 6, - STATIC_DOUBLE, // T_DOUBLE = 7, - STATIC_BYTE, // T_BYTE = 8, - STATIC_SHORT, // T_SHORT = 9, - STATIC_WORD, // T_INT = 10, - STATIC_DOUBLE, // T_LONG = 11, - STATIC_OOP, // T_OBJECT = 12, - STATIC_OOP, // T_ARRAY = 13, - BAD_ALLOCATION_TYPE, // T_VOID = 14, - BAD_ALLOCATION_TYPE, // T_ADDRESS = 15, - BAD_ALLOCATION_TYPE, // T_NARROWOOP = 16, - BAD_ALLOCATION_TYPE, // T_METADATA = 17, - BAD_ALLOCATION_TYPE, // T_NARROWKLASS = 18, - BAD_ALLOCATION_TYPE, // T_CONFLICT = 19, -}; - -static FieldAllocationType basic_type_to_atype(bool is_static, BasicType type) { - assert(type >= T_BOOLEAN && type < T_VOID, "only allowable values"); - FieldAllocationType result = _basic_type_to_atype[type + (is_static ? (T_CONFLICT + 1) : 0)]; - assert(result != BAD_ALLOCATION_TYPE, "bad type"); - return result; -} - -class FieldAllocationCount: public ResourceObj { - public: - u2 count[MAX_FIELD_ALLOCATION_TYPE]; - - FieldAllocationCount() { - for (int i = 0; i < MAX_FIELD_ALLOCATION_TYPE; i++) { - count[i] = 0; - } - } - - FieldAllocationType update(bool is_static, BasicType type) { - FieldAllocationType atype = basic_type_to_atype(is_static, type); - // Make sure there is no overflow with injected fields. - assert(count[atype] < 0xFFFF, "More than 65535 fields"); - count[atype]++; - return atype; - } -}; - -Array* ClassFileParser::parse_fields(Symbol* class_name, - bool is_interface, - FieldAllocationCount *fac, - u2* java_fields_count_ptr, TRAPS) { - ClassFileStream* cfs = stream(); - cfs->guarantee_more(2, CHECK_NULL); // length - u2 length = cfs->get_u2_fast(); - *java_fields_count_ptr = length; - - int num_injected = 0; - InjectedField* injected = JavaClasses::get_injected(class_name, &num_injected); - int total_fields = length + num_injected; - - // The field array starts with tuples of shorts - // [access, name index, sig index, initial value index, byte offset]. - // A generic signature slot only exists for field with generic - // signature attribute. And the access flag is set with - // JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE for that field. The generic - // signature slots are at the end of the field array and after all - // other fields data. - // - // f1: [access, name index, sig index, initial value index, low_offset, high_offset] - // f2: [access, name index, sig index, initial value index, low_offset, high_offset] - // ... - // fn: [access, name index, sig index, initial value index, low_offset, high_offset] - // [generic signature index] - // [generic signature index] - // ... - // - // Allocate a temporary resource array for field data. For each field, - // a slot is reserved in the temporary array for the generic signature - // index. After parsing all fields, the data are copied to a permanent - // array and any unused slots will be discarded. - ResourceMark rm(THREAD); - u2* fa = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, u2, total_fields * (FieldInfo::field_slots + 1)); - - // The generic signature slots start after all other fields' data. - int generic_signature_slot = total_fields * FieldInfo::field_slots; - int num_generic_signature = 0; - for (int n = 0; n < length; n++) { - cfs->guarantee_more(8, CHECK_NULL); // access_flags, name_index, descriptor_index, attributes_count - - AccessFlags access_flags; - jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_FIELD_MODIFIERS; - verify_legal_field_modifiers(flags, is_interface, CHECK_NULL); - access_flags.set_flags(flags); - - u2 name_index = cfs->get_u2_fast(); - int cp_size = _cp->length(); - check_property(valid_symbol_at(name_index), - "Invalid constant pool index %u for field name in class file %s", - name_index, - CHECK_NULL); - Symbol* name = _cp->symbol_at(name_index); - verify_legal_field_name(name, CHECK_NULL); - - u2 signature_index = cfs->get_u2_fast(); - check_property(valid_symbol_at(signature_index), - "Invalid constant pool index %u for field signature in class file %s", - signature_index, CHECK_NULL); - Symbol* sig = _cp->symbol_at(signature_index); - verify_legal_field_signature(name, sig, CHECK_NULL); - - u2 constantvalue_index = 0; - bool is_synthetic = false; - u2 generic_signature_index = 0; - bool is_static = access_flags.is_static(); - FieldAnnotationCollector parsed_annotations(_loader_data); - - u2 attributes_count = cfs->get_u2_fast(); - if (attributes_count > 0) { - parse_field_attributes(attributes_count, is_static, signature_index, - &constantvalue_index, &is_synthetic, - &generic_signature_index, &parsed_annotations, - CHECK_NULL); - if (parsed_annotations.field_annotations() != NULL) { - if (_fields_annotations == NULL) { - _fields_annotations = MetadataFactory::new_array( - _loader_data, length, NULL, - CHECK_NULL); - } - _fields_annotations->at_put(n, parsed_annotations.field_annotations()); - parsed_annotations.set_field_annotations(NULL); - } - if (parsed_annotations.field_type_annotations() != NULL) { - if (_fields_type_annotations == NULL) { - _fields_type_annotations = MetadataFactory::new_array( - _loader_data, length, NULL, - CHECK_NULL); - } - _fields_type_annotations->at_put(n, parsed_annotations.field_type_annotations()); - parsed_annotations.set_field_type_annotations(NULL); - } - - if (is_synthetic) { - access_flags.set_is_synthetic(); - } - if (generic_signature_index != 0) { - access_flags.set_field_has_generic_signature(); - fa[generic_signature_slot] = generic_signature_index; - generic_signature_slot ++; - num_generic_signature ++; - } - } - - FieldInfo* field = FieldInfo::from_field_array(fa, n); - field->initialize(access_flags.as_short(), - name_index, - signature_index, - constantvalue_index); - BasicType type = _cp->basic_type_for_signature_at(signature_index); - - // Remember how many oops we encountered and compute allocation type - FieldAllocationType atype = fac->update(is_static, type); - field->set_allocation_type(atype); - - // After field is initialized with type, we can augment it with aux info - if (parsed_annotations.has_any_annotations()) - parsed_annotations.apply_to(field); - } - - int index = length; - if (num_injected != 0) { - for (int n = 0; n < num_injected; n++) { - // Check for duplicates - if (injected[n].may_be_java) { - Symbol* name = injected[n].name(); - Symbol* signature = injected[n].signature(); - bool duplicate = false; - for (int i = 0; i < length; i++) { - FieldInfo* f = FieldInfo::from_field_array(fa, i); - if (name == _cp->symbol_at(f->name_index()) && - signature == _cp->symbol_at(f->signature_index())) { - // Symbol is desclared in Java so skip this one - duplicate = true; - break; - } - } - if (duplicate) { - // These will be removed from the field array at the end - continue; - } - } - - // Injected field - FieldInfo* field = FieldInfo::from_field_array(fa, index); - field->initialize(JVM_ACC_FIELD_INTERNAL, - injected[n].name_index, - injected[n].signature_index, - 0); - - BasicType type = FieldType::basic_type(injected[n].signature()); - - // Remember how many oops we encountered and compute allocation type - FieldAllocationType atype = fac->update(false, type); - field->set_allocation_type(atype); - index++; - } - } - - // Now copy the fields' data from the temporary resource array. - // Sometimes injected fields already exist in the Java source so - // the fields array could be too long. In that case the - // fields array is trimed. Also unused slots that were reserved - // for generic signature indexes are discarded. - Array* fields = MetadataFactory::new_array( - _loader_data, index * FieldInfo::field_slots + num_generic_signature, - CHECK_NULL); - _fields = fields; // save in case of error - { - int i = 0; - for (; i < index * FieldInfo::field_slots; i++) { - fields->at_put(i, fa[i]); - } - for (int j = total_fields * FieldInfo::field_slots; - j < generic_signature_slot; j++) { - fields->at_put(i++, fa[j]); - } - assert(i == fields->length(), ""); - } - - if (_need_verify && length > 1) { - // Check duplicated fields - ResourceMark rm(THREAD); - NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, NameSigHash*, HASH_ROW_SIZE); - initialize_hashtable(names_and_sigs); - bool dup = false; - { - debug_only(No_Safepoint_Verifier nsv;) - for (AllFieldStream fs(fields, _cp); !fs.done(); fs.next()) { - Symbol* name = fs.name(); - Symbol* sig = fs.signature(); - // If no duplicates, add name/signature in hashtable names_and_sigs. - if (!put_after_lookup(name, sig, names_and_sigs)) { - dup = true; - break; - } - } - } - if (dup) { - classfile_parse_error("Duplicate field name&signature in class file %s", - CHECK_NULL); - } - } - - return fields; -} - - -static void copy_u2_with_conversion(u2* dest, u2* src, int length) { - while (length-- > 0) { - *dest++ = Bytes::get_Java_u2((u1*) (src++)); - } -} - - -u2* ClassFileParser::parse_exception_table(u4 code_length, - u4 exception_table_length, - TRAPS) { - ClassFileStream* cfs = stream(); - - u2* exception_table_start = cfs->get_u2_buffer(); - assert(exception_table_start != NULL, "null exception table"); - cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc, end_pc, handler_pc, catch_type_index - // Will check legal target after parsing code array in verifier. - if (_need_verify) { - for (unsigned int i = 0; i < exception_table_length; i++) { - u2 start_pc = cfs->get_u2_fast(); - u2 end_pc = cfs->get_u2_fast(); - u2 handler_pc = cfs->get_u2_fast(); - u2 catch_type_index = cfs->get_u2_fast(); - guarantee_property((start_pc < end_pc) && (end_pc <= code_length), - "Illegal exception table range in class file %s", - CHECK_NULL); - guarantee_property(handler_pc < code_length, - "Illegal exception table handler in class file %s", - CHECK_NULL); - if (catch_type_index != 0) { - guarantee_property(valid_klass_reference_at(catch_type_index), - "Catch type in exception table has bad constant type in class file %s", CHECK_NULL); - } - } - } else { - cfs->skip_u2_fast(exception_table_length * 4); - } - return exception_table_start; -} - -void ClassFileParser::parse_linenumber_table( - u4 code_attribute_length, u4 code_length, - CompressedLineNumberWriteStream** write_stream, TRAPS) { - ClassFileStream* cfs = stream(); - unsigned int num_entries = cfs->get_u2(CHECK); - - // Each entry is a u2 start_pc, and a u2 line_number - unsigned int length_in_bytes = num_entries * (sizeof(u2) + sizeof(u2)); - - // Verify line number attribute and table length - check_property( - code_attribute_length == sizeof(u2) + length_in_bytes, - "LineNumberTable attribute has wrong length in class file %s", CHECK); - - cfs->guarantee_more(length_in_bytes, CHECK); - - if ((*write_stream) == NULL) { - if (length_in_bytes > fixed_buffer_size) { - (*write_stream) = new CompressedLineNumberWriteStream(length_in_bytes); - } else { - (*write_stream) = new CompressedLineNumberWriteStream( - linenumbertable_buffer, fixed_buffer_size); - } - } - - while (num_entries-- > 0) { - u2 bci = cfs->get_u2_fast(); // start_pc - u2 line = cfs->get_u2_fast(); // line_number - guarantee_property(bci < code_length, - "Invalid pc in LineNumberTable in class file %s", CHECK); - (*write_stream)->write_pair(bci, line); - } -} - - -// Class file LocalVariableTable elements. -class Classfile_LVT_Element VALUE_OBJ_CLASS_SPEC { - public: - u2 start_bci; - u2 length; - u2 name_cp_index; - u2 descriptor_cp_index; - u2 slot; -}; - - -class LVT_Hash: public CHeapObj { - public: - LocalVariableTableElement *_elem; // element - LVT_Hash* _next; // Next entry in hash table -}; - -unsigned int hash(LocalVariableTableElement *elem) { - unsigned int raw_hash = elem->start_bci; - - raw_hash = elem->length + raw_hash * 37; - raw_hash = elem->name_cp_index + raw_hash * 37; - raw_hash = elem->slot + raw_hash * 37; - - return raw_hash % HASH_ROW_SIZE; -} - -void initialize_hashtable(LVT_Hash** table) { - for (int i = 0; i < HASH_ROW_SIZE; i++) { - table[i] = NULL; - } -} - -void clear_hashtable(LVT_Hash** table) { - for (int i = 0; i < HASH_ROW_SIZE; i++) { - LVT_Hash* current = table[i]; - LVT_Hash* next; - while (current != NULL) { - next = current->_next; - current->_next = NULL; - delete(current); - current = next; - } - table[i] = NULL; - } -} - -LVT_Hash* LVT_lookup(LocalVariableTableElement *elem, int index, LVT_Hash** table) { - LVT_Hash* entry = table[index]; - - /* - * 3-tuple start_bci/length/slot has to be unique key, - * so the following comparison seems to be redundant: - * && elem->name_cp_index == entry->_elem->name_cp_index - */ - while (entry != NULL) { - if (elem->start_bci == entry->_elem->start_bci - && elem->length == entry->_elem->length - && elem->name_cp_index == entry->_elem->name_cp_index - && elem->slot == entry->_elem->slot - ) { - return entry; - } - entry = entry->_next; - } - return NULL; -} - -// Return false if the local variable is found in table. -// Return true if no duplicate is found. -// And local variable is added as a new entry in table. -bool LVT_put_after_lookup(LocalVariableTableElement *elem, LVT_Hash** table) { - // First lookup for duplicates - int index = hash(elem); - LVT_Hash* entry = LVT_lookup(elem, index, table); - - if (entry != NULL) { - return false; - } - // No duplicate is found, allocate a new entry and fill it. - if ((entry = new LVT_Hash()) == NULL) { - return false; - } - entry->_elem = elem; - - // Insert into hash table - entry->_next = table[index]; - table[index] = entry; - - return true; -} - -void copy_lvt_element(Classfile_LVT_Element *src, LocalVariableTableElement *lvt) { - lvt->start_bci = Bytes::get_Java_u2((u1*) &src->start_bci); - lvt->length = Bytes::get_Java_u2((u1*) &src->length); - lvt->name_cp_index = Bytes::get_Java_u2((u1*) &src->name_cp_index); - lvt->descriptor_cp_index = Bytes::get_Java_u2((u1*) &src->descriptor_cp_index); - lvt->signature_cp_index = 0; - lvt->slot = Bytes::get_Java_u2((u1*) &src->slot); -} - -// Function is used to parse both attributes: -// LocalVariableTable (LVT) and LocalVariableTypeTable (LVTT) -u2* ClassFileParser::parse_localvariable_table(u4 code_length, - u2 max_locals, - u4 code_attribute_length, - u2* localvariable_table_length, - bool isLVTT, - TRAPS) { - ClassFileStream* cfs = stream(); - const char * tbl_name = (isLVTT) ? "LocalVariableTypeTable" : "LocalVariableTable"; - *localvariable_table_length = cfs->get_u2(CHECK_NULL); - unsigned int size = (*localvariable_table_length) * sizeof(Classfile_LVT_Element) / sizeof(u2); - // Verify local variable table attribute has right length - if (_need_verify) { - guarantee_property(code_attribute_length == (sizeof(*localvariable_table_length) + size * sizeof(u2)), - "%s has wrong length in class file %s", tbl_name, CHECK_NULL); - } - u2* localvariable_table_start = cfs->get_u2_buffer(); - assert(localvariable_table_start != NULL, "null local variable table"); - if (!_need_verify) { - cfs->skip_u2_fast(size); - } else { - cfs->guarantee_more(size * 2, CHECK_NULL); - for(int i = 0; i < (*localvariable_table_length); i++) { - u2 start_pc = cfs->get_u2_fast(); - u2 length = cfs->get_u2_fast(); - u2 name_index = cfs->get_u2_fast(); - u2 descriptor_index = cfs->get_u2_fast(); - u2 index = cfs->get_u2_fast(); - // Assign to a u4 to avoid overflow - u4 end_pc = (u4)start_pc + (u4)length; - - if (start_pc >= code_length) { - classfile_parse_error( - "Invalid start_pc %u in %s in class file %s", - start_pc, tbl_name, CHECK_NULL); - } - if (end_pc > code_length) { - classfile_parse_error( - "Invalid length %u in %s in class file %s", - length, tbl_name, CHECK_NULL); - } - int cp_size = _cp->length(); - guarantee_property(valid_symbol_at(name_index), - "Name index %u in %s has bad constant type in class file %s", - name_index, tbl_name, CHECK_NULL); - guarantee_property(valid_symbol_at(descriptor_index), - "Signature index %u in %s has bad constant type in class file %s", - descriptor_index, tbl_name, CHECK_NULL); - - Symbol* name = _cp->symbol_at(name_index); - Symbol* sig = _cp->symbol_at(descriptor_index); - verify_legal_field_name(name, CHECK_NULL); - u2 extra_slot = 0; - if (!isLVTT) { - verify_legal_field_signature(name, sig, CHECK_NULL); - - // 4894874: check special cases for double and long local variables - if (sig == vmSymbols::type_signature(T_DOUBLE) || - sig == vmSymbols::type_signature(T_LONG)) { - extra_slot = 1; - } - } - guarantee_property((index + extra_slot) < max_locals, - "Invalid index %u in %s in class file %s", - index, tbl_name, CHECK_NULL); - } - } - return localvariable_table_start; -} - - -void ClassFileParser::parse_type_array(u2 array_length, u4 code_length, u4* u1_index, u4* u2_index, - u1* u1_array, u2* u2_array, TRAPS) { - ClassFileStream* cfs = stream(); - u2 index = 0; // index in the array with long/double occupying two slots - u4 i1 = *u1_index; - u4 i2 = *u2_index + 1; - for(int i = 0; i < array_length; i++) { - u1 tag = u1_array[i1++] = cfs->get_u1(CHECK); - index++; - if (tag == ITEM_Long || tag == ITEM_Double) { - index++; - } else if (tag == ITEM_Object) { - u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK); - guarantee_property(valid_klass_reference_at(class_index), - "Bad class index %u in StackMap in class file %s", - class_index, CHECK); - } else if (tag == ITEM_Uninitialized) { - u2 offset = u2_array[i2++] = cfs->get_u2(CHECK); - guarantee_property( - offset < code_length, - "Bad uninitialized type offset %u in StackMap in class file %s", - offset, CHECK); - } else { - guarantee_property( - tag <= (u1)ITEM_Uninitialized, - "Unknown variable type %u in StackMap in class file %s", - tag, CHECK); - } - } - u2_array[*u2_index] = index; - *u1_index = i1; - *u2_index = i2; -} - -u1* ClassFileParser::parse_stackmap_table( - u4 code_attribute_length, TRAPS) { - if (code_attribute_length == 0) - return NULL; - - ClassFileStream* cfs = stream(); - u1* stackmap_table_start = cfs->get_u1_buffer(); - assert(stackmap_table_start != NULL, "null stackmap table"); - - // check code_attribute_length first - stream()->skip_u1(code_attribute_length, CHECK_NULL); - - if (!_need_verify && !DumpSharedSpaces) { - return NULL; - } - return stackmap_table_start; -} - -u2* ClassFileParser::parse_checked_exceptions(u2* checked_exceptions_length, - u4 method_attribute_length, - TRAPS) { - ClassFileStream* cfs = stream(); - cfs->guarantee_more(2, CHECK_NULL); // checked_exceptions_length - *checked_exceptions_length = cfs->get_u2_fast(); - unsigned int size = (*checked_exceptions_length) * sizeof(CheckedExceptionElement) / sizeof(u2); - u2* checked_exceptions_start = cfs->get_u2_buffer(); - assert(checked_exceptions_start != NULL, "null checked exceptions"); - if (!_need_verify) { - cfs->skip_u2_fast(size); - } else { - // Verify each value in the checked exception table - u2 checked_exception; - u2 len = *checked_exceptions_length; - cfs->guarantee_more(2 * len, CHECK_NULL); - for (int i = 0; i < len; i++) { - checked_exception = cfs->get_u2_fast(); - check_property( - valid_klass_reference_at(checked_exception), - "Exception name has bad type at constant pool %u in class file %s", - checked_exception, CHECK_NULL); - } - } - // check exceptions attribute length - if (_need_verify) { - guarantee_property(method_attribute_length == (sizeof(*checked_exceptions_length) + - sizeof(u2) * size), - "Exceptions attribute has wrong length in class file %s", CHECK_NULL); - } - return checked_exceptions_start; -} - -void ClassFileParser::throwIllegalSignature( - const char* type, Symbol* name, Symbol* sig, TRAPS) { - ResourceMark rm(THREAD); - Exceptions::fthrow(THREAD_AND_LOCATION, - vmSymbols::java_lang_ClassFormatError(), - "%s \"%s\" in class %s has illegal signature \"%s\"", type, - name->as_C_string(), _class_name->as_C_string(), sig->as_C_string()); -} - -// Skip an annotation. Return >=limit if there is any problem. -int ClassFileParser::skip_annotation(u1* buffer, int limit, int index) { - // annotation := atype:u2 do(nmem:u2) {member:u2 value} - // value := switch (tag:u1) { ... } - index += 2; // skip atype - if ((index += 2) >= limit) return limit; // read nmem - int nmem = Bytes::get_Java_u2(buffer+index-2); - while (--nmem >= 0 && index < limit) { - index += 2; // skip member - index = skip_annotation_value(buffer, limit, index); - } - return index; -} - -// Skip an annotation value. Return >=limit if there is any problem. -int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) { - // value := switch (tag:u1) { - // case B, C, I, S, Z, D, F, J, c: con:u2; - // case e: e_class:u2 e_name:u2; - // case s: s_con:u2; - // case [: do(nval:u2) {value}; - // case @: annotation; - // case s: s_con:u2; - // } - if ((index += 1) >= limit) return limit; // read tag - u1 tag = buffer[index-1]; - switch (tag) { - case 'B': case 'C': case 'I': case 'S': case 'Z': - case 'D': case 'F': case 'J': case 'c': case 's': - index += 2; // skip con or s_con - break; - case 'e': - index += 4; // skip e_class, e_name - break; - case '[': - { - if ((index += 2) >= limit) return limit; // read nval - int nval = Bytes::get_Java_u2(buffer+index-2); - while (--nval >= 0 && index < limit) { - index = skip_annotation_value(buffer, limit, index); - } - } - break; - case '@': - index = skip_annotation(buffer, limit, index); - break; - default: - assert(false, "annotation tag"); - return limit; // bad tag byte - } - return index; -} - -// Sift through annotations, looking for those significant to the VM: -void ClassFileParser::parse_annotations(u1* buffer, int limit, - ClassFileParser::AnnotationCollector* coll, - TRAPS) { - // annotations := do(nann:u2) {annotation} - int index = 0; - if ((index += 2) >= limit) return; // read nann - int nann = Bytes::get_Java_u2(buffer+index-2); - enum { // initial annotation layout - atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;' - count_off = 2, // u2 such as 1 (one value) - member_off = 4, // utf8 such as 'value' - tag_off = 6, // u1 such as 'c' (type) or 'e' (enum) - e_tag_val = 'e', - e_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;' - e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME' - e_size = 11, // end of 'e' annotation - c_tag_val = 'c', // payload is type - c_con_off = 7, // utf8 payload, such as 'I' - c_size = 9, // end of 'c' annotation - s_tag_val = 's', // payload is String - s_con_off = 7, // utf8 payload, such as 'Ljava/lang/String;' - s_size = 9, - min_size = 6 // smallest possible size (zero members) - }; - while ((--nann) >= 0 && (index-2 + min_size <= limit)) { - int index0 = index; - index = skip_annotation(buffer, limit, index); - u1* abase = buffer + index0; - int atype = Bytes::get_Java_u2(abase + atype_off); - int count = Bytes::get_Java_u2(abase + count_off); - Symbol* aname = check_symbol_at(_cp, atype); - if (aname == NULL) break; // invalid annotation name - Symbol* member = NULL; - if (count >= 1) { - int member_index = Bytes::get_Java_u2(abase + member_off); - member = check_symbol_at(_cp, member_index); - if (member == NULL) break; // invalid member name - } - - // Here is where parsing particular annotations will take place. - AnnotationCollector::ID id = coll->annotation_index(_loader_data, aname); - if (id == AnnotationCollector::_unknown) continue; - coll->set_annotation(id); - - if (id == AnnotationCollector::_sun_misc_Contended) { - // @Contended can optionally specify the contention group. - // - // Contended group defines the equivalence class over the fields: - // the fields within the same contended group are not treated distinct. - // The only exception is default group, which does not incur the - // equivalence. Naturally, contention group for classes is meaningless. - // - // While the contention group is specified as String, annotation - // values are already interned, and we might as well use the constant - // pool index as the group tag. - // - u2 group_index = 0; // default contended group - if (count == 1 - && s_size == (index - index0) // match size - && s_tag_val == *(abase + tag_off) - && member == vmSymbols::value_name()) { - group_index = Bytes::get_Java_u2(abase + s_con_off); - if (_cp->symbol_at(group_index)->utf8_length() == 0) { - group_index = 0; // default contended group - } - } - coll->set_contended_group(group_index); - } - } -} - -ClassFileParser::AnnotationCollector::ID -ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_data, - Symbol* name) { - vmSymbols::SID sid = vmSymbols::find_sid(name); - // Privileged code can use all annotations. Other code silently drops some. - const bool privileged = loader_data->is_the_null_class_loader_data() || - loader_data->is_ext_class_loader_data() || - loader_data->is_anonymous(); - switch (sid) { - case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_reflect_CallerSensitive_signature): - if (_location != _in_method) break; // only allow for methods - if (!privileged) break; // only allow in privileged code - return _method_CallerSensitive; - case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature): - if (_location != _in_method) break; // only allow for methods - if (!privileged) break; // only allow in privileged code - return _method_ForceInline; - case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature): - if (_location != _in_method) break; // only allow for methods - if (!privileged) break; // only allow in privileged code - return _method_DontInline; - case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature): - if (_location != _in_method) break; // only allow for methods - if (!privileged) break; // only allow in privileged code - return _method_LambdaForm_Compiled; - case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature): - if (_location != _in_method) break; // only allow for methods - if (!privileged) break; // only allow in privileged code - return _method_LambdaForm_Hidden; - case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_Stable_signature): - if (_location != _in_field) break; // only allow for fields - if (!privileged) break; // only allow in privileged code - return _field_Stable; - case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_misc_Contended_signature): - if (_location != _in_field && _location != _in_class) break; // only allow for fields and classes - if (!EnableContended || (RestrictContended && !privileged)) break; // honor privileges - return _sun_misc_Contended; - default: break; - } - return AnnotationCollector::_unknown; -} - -void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) { - if (is_contended()) - f->set_contended_group(contended_group()); - if (is_stable()) - f->set_stable(true); -} - -ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector() { - // If there's an error deallocate metadata for field annotations - MetadataFactory::free_array(_loader_data, _field_annotations); - MetadataFactory::free_array(_loader_data, _field_type_annotations); -} - -void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) { - if (has_annotation(_method_CallerSensitive)) - m->set_caller_sensitive(true); - if (has_annotation(_method_ForceInline)) - m->set_force_inline(true); - if (has_annotation(_method_DontInline)) - m->set_dont_inline(true); - if (has_annotation(_method_LambdaForm_Compiled) && m->intrinsic_id() == vmIntrinsics::_none) - m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm); - if (has_annotation(_method_LambdaForm_Hidden)) - m->set_hidden(true); -} - -void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) { - k->set_is_contended(is_contended()); -} - - -#define MAX_ARGS_SIZE 255 -#define MAX_CODE_SIZE 65535 -#define INITIAL_MAX_LVT_NUMBER 256 - -/* Copy class file LVT's/LVTT's into the HotSpot internal LVT. - * - * Rules for LVT's and LVTT's are: - * - There can be any number of LVT's and LVTT's. - * - If there are n LVT's, it is the same as if there was just - * one LVT containing all the entries from the n LVT's. - * - There may be no more than one LVT entry per local variable. - * Two LVT entries are 'equal' if these fields are the same: - * start_pc, length, name, slot - * - There may be no more than one LVTT entry per each LVT entry. - * Each LVTT entry has to match some LVT entry. - * - HotSpot internal LVT keeps natural ordering of class file LVT entries. - */ -void ClassFileParser::copy_localvariable_table(ConstMethod* cm, - int lvt_cnt, - u2* localvariable_table_length, - u2** localvariable_table_start, - int lvtt_cnt, - u2* localvariable_type_table_length, - u2** localvariable_type_table_start, - TRAPS) { - - LVT_Hash** lvt_Hash = NEW_RESOURCE_ARRAY(LVT_Hash*, HASH_ROW_SIZE); - initialize_hashtable(lvt_Hash); - - // To fill LocalVariableTable in - Classfile_LVT_Element* cf_lvt; - LocalVariableTableElement* lvt = cm->localvariable_table_start(); - - for (int tbl_no = 0; tbl_no < lvt_cnt; tbl_no++) { - cf_lvt = (Classfile_LVT_Element *) localvariable_table_start[tbl_no]; - for (int idx = 0; idx < localvariable_table_length[tbl_no]; idx++, lvt++) { - copy_lvt_element(&cf_lvt[idx], lvt); - // If no duplicates, add LVT elem in hashtable lvt_Hash. - if (LVT_put_after_lookup(lvt, lvt_Hash) == false - && _need_verify - && _major_version >= JAVA_1_5_VERSION) { - clear_hashtable(lvt_Hash); - classfile_parse_error("Duplicated LocalVariableTable attribute " - "entry for '%s' in class file %s", - _cp->symbol_at(lvt->name_cp_index)->as_utf8(), - CHECK); - } - } - } - - // To merge LocalVariableTable and LocalVariableTypeTable - Classfile_LVT_Element* cf_lvtt; - LocalVariableTableElement lvtt_elem; - - for (int tbl_no = 0; tbl_no < lvtt_cnt; tbl_no++) { - cf_lvtt = (Classfile_LVT_Element *) localvariable_type_table_start[tbl_no]; - for (int idx = 0; idx < localvariable_type_table_length[tbl_no]; idx++) { - copy_lvt_element(&cf_lvtt[idx], &lvtt_elem); - int index = hash(&lvtt_elem); - LVT_Hash* entry = LVT_lookup(&lvtt_elem, index, lvt_Hash); - if (entry == NULL) { - if (_need_verify) { - clear_hashtable(lvt_Hash); - classfile_parse_error("LVTT entry for '%s' in class file %s " - "does not match any LVT entry", - _cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(), - CHECK); - } - } else if (entry->_elem->signature_cp_index != 0 && _need_verify) { - clear_hashtable(lvt_Hash); - classfile_parse_error("Duplicated LocalVariableTypeTable attribute " - "entry for '%s' in class file %s", - _cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(), - CHECK); - } else { - // to add generic signatures into LocalVariableTable - entry->_elem->signature_cp_index = lvtt_elem.descriptor_cp_index; - } - } - } - clear_hashtable(lvt_Hash); -} - - -void ClassFileParser::copy_method_annotations(ConstMethod* cm, - u1* runtime_visible_annotations, - int runtime_visible_annotations_length, - u1* runtime_invisible_annotations, - int runtime_invisible_annotations_length, - u1* runtime_visible_parameter_annotations, - int runtime_visible_parameter_annotations_length, - u1* runtime_invisible_parameter_annotations, - int runtime_invisible_parameter_annotations_length, - u1* runtime_visible_type_annotations, - int runtime_visible_type_annotations_length, - u1* runtime_invisible_type_annotations, - int runtime_invisible_type_annotations_length, - u1* annotation_default, - int annotation_default_length, - TRAPS) { - - AnnotationArray* a; - - if (runtime_visible_annotations_length + - runtime_invisible_annotations_length > 0) { - a = assemble_annotations(runtime_visible_annotations, - runtime_visible_annotations_length, - runtime_invisible_annotations, - runtime_invisible_annotations_length, - CHECK); - cm->set_method_annotations(a); - } - - if (runtime_visible_parameter_annotations_length + - runtime_invisible_parameter_annotations_length > 0) { - a = assemble_annotations(runtime_visible_parameter_annotations, - runtime_visible_parameter_annotations_length, - runtime_invisible_parameter_annotations, - runtime_invisible_parameter_annotations_length, - CHECK); - cm->set_parameter_annotations(a); - } - - if (annotation_default_length > 0) { - a = assemble_annotations(annotation_default, - annotation_default_length, - NULL, - 0, - CHECK); - cm->set_default_annotations(a); - } - - if (runtime_visible_type_annotations_length + - runtime_invisible_type_annotations_length > 0) { - a = assemble_annotations(runtime_visible_type_annotations, - runtime_visible_type_annotations_length, - runtime_invisible_type_annotations, - runtime_invisible_type_annotations_length, - CHECK); - cm->set_type_annotations(a); - } -} - - -// Note: the parse_method below is big and clunky because all parsing of the code and exceptions -// attribute is inlined. This is cumbersome to avoid since we inline most of the parts in the -// Method* to save footprint, so we only know the size of the resulting Method* when the -// entire method attribute is parsed. -// -// The promoted_flags parameter is used to pass relevant access_flags -// from the method back up to the containing klass. These flag values -// are added to klass's access_flags. - -methodHandle ClassFileParser::parse_method(bool is_interface, - AccessFlags *promoted_flags, - TRAPS) { - ClassFileStream* cfs = stream(); - methodHandle nullHandle; - ResourceMark rm(THREAD); - // Parse fixed parts - cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count - - int flags = cfs->get_u2_fast(); - u2 name_index = cfs->get_u2_fast(); - int cp_size = _cp->length(); - check_property( - valid_symbol_at(name_index), - "Illegal constant pool index %u for method name in class file %s", - name_index, CHECK_(nullHandle)); - Symbol* name = _cp->symbol_at(name_index); - verify_legal_method_name(name, CHECK_(nullHandle)); - - u2 signature_index = cfs->get_u2_fast(); - guarantee_property( - valid_symbol_at(signature_index), - "Illegal constant pool index %u for method signature in class file %s", - signature_index, CHECK_(nullHandle)); - Symbol* signature = _cp->symbol_at(signature_index); - - AccessFlags access_flags; - if (name == vmSymbols::class_initializer_name()) { - // We ignore the other access flags for a valid class initializer. - // (JVM Spec 2nd ed., chapter 4.6) - if (_major_version < 51) { // backward compatibility - flags = JVM_ACC_STATIC; - } else if ((flags & JVM_ACC_STATIC) == JVM_ACC_STATIC) { - flags &= JVM_ACC_STATIC | JVM_ACC_STRICT; - } - } else { - verify_legal_method_modifiers(flags, is_interface, name, CHECK_(nullHandle)); - } - - int args_size = -1; // only used when _need_verify is true - if (_need_verify) { - args_size = ((flags & JVM_ACC_STATIC) ? 0 : 1) + - verify_legal_method_signature(name, signature, CHECK_(nullHandle)); - if (args_size > MAX_ARGS_SIZE) { - classfile_parse_error("Too many arguments in method signature in class file %s", CHECK_(nullHandle)); - } - } - - access_flags.set_flags(flags & JVM_RECOGNIZED_METHOD_MODIFIERS); - - // Default values for code and exceptions attribute elements - u2 max_stack = 0; - u2 max_locals = 0; - u4 code_length = 0; - u1* code_start = 0; - u2 exception_table_length = 0; - u2* exception_table_start = NULL; - Array* exception_handlers = Universe::the_empty_int_array(); - u2 checked_exceptions_length = 0; - u2* checked_exceptions_start = NULL; - CompressedLineNumberWriteStream* linenumber_table = NULL; - int linenumber_table_length = 0; - int total_lvt_length = 0; - u2 lvt_cnt = 0; - u2 lvtt_cnt = 0; - bool lvt_allocated = false; - u2 max_lvt_cnt = INITIAL_MAX_LVT_NUMBER; - u2 max_lvtt_cnt = INITIAL_MAX_LVT_NUMBER; - u2* localvariable_table_length; - u2** localvariable_table_start; - u2* localvariable_type_table_length; - u2** localvariable_type_table_start; - u2 method_parameters_length = 0; - u1* method_parameters_data = NULL; - bool method_parameters_seen = false; - bool parsed_code_attribute = false; - bool parsed_checked_exceptions_attribute = false; - bool parsed_stackmap_attribute = false; - // stackmap attribute - JDK1.5 - u1* stackmap_data = NULL; - int stackmap_data_length = 0; - u2 generic_signature_index = 0; - MethodAnnotationCollector parsed_annotations; - u1* runtime_visible_annotations = NULL; - int runtime_visible_annotations_length = 0; - u1* runtime_invisible_annotations = NULL; - int runtime_invisible_annotations_length = 0; - u1* runtime_visible_parameter_annotations = NULL; - int runtime_visible_parameter_annotations_length = 0; - u1* runtime_invisible_parameter_annotations = NULL; - int runtime_invisible_parameter_annotations_length = 0; - u1* runtime_visible_type_annotations = NULL; - int runtime_visible_type_annotations_length = 0; - u1* runtime_invisible_type_annotations = NULL; - int runtime_invisible_type_annotations_length = 0; - bool runtime_invisible_annotations_exists = false; - bool runtime_invisible_type_annotations_exists = false; - bool runtime_invisible_parameter_annotations_exists = false; - u1* annotation_default = NULL; - int annotation_default_length = 0; - - // Parse code and exceptions attribute - u2 method_attributes_count = cfs->get_u2_fast(); - while (method_attributes_count--) { - cfs->guarantee_more(6, CHECK_(nullHandle)); // method_attribute_name_index, method_attribute_length - u2 method_attribute_name_index = cfs->get_u2_fast(); - u4 method_attribute_length = cfs->get_u4_fast(); - check_property( - valid_symbol_at(method_attribute_name_index), - "Invalid method attribute name index %u in class file %s", - method_attribute_name_index, CHECK_(nullHandle)); - - Symbol* method_attribute_name = _cp->symbol_at(method_attribute_name_index); - if (method_attribute_name == vmSymbols::tag_code()) { - // Parse Code attribute - if (_need_verify) { - guarantee_property( - !access_flags.is_native() && !access_flags.is_abstract(), - "Code attribute in native or abstract methods in class file %s", - CHECK_(nullHandle)); - } - if (parsed_code_attribute) { - classfile_parse_error("Multiple Code attributes in class file %s", CHECK_(nullHandle)); - } - parsed_code_attribute = true; - - // Stack size, locals size, and code size - if (_major_version == 45 && _minor_version <= 2) { - cfs->guarantee_more(4, CHECK_(nullHandle)); - max_stack = cfs->get_u1_fast(); - max_locals = cfs->get_u1_fast(); - code_length = cfs->get_u2_fast(); - } else { - cfs->guarantee_more(8, CHECK_(nullHandle)); - max_stack = cfs->get_u2_fast(); - max_locals = cfs->get_u2_fast(); - code_length = cfs->get_u4_fast(); - } - if (_need_verify) { - guarantee_property(args_size <= max_locals, - "Arguments can't fit into locals in class file %s", CHECK_(nullHandle)); - guarantee_property(code_length > 0 && code_length <= MAX_CODE_SIZE, - "Invalid method Code length %u in class file %s", - code_length, CHECK_(nullHandle)); - } - // Code pointer - code_start = cfs->get_u1_buffer(); - assert(code_start != NULL, "null code start"); - cfs->guarantee_more(code_length, CHECK_(nullHandle)); - cfs->skip_u1_fast(code_length); - - // Exception handler table - cfs->guarantee_more(2, CHECK_(nullHandle)); // exception_table_length - exception_table_length = cfs->get_u2_fast(); - if (exception_table_length > 0) { - exception_table_start = - parse_exception_table(code_length, exception_table_length, CHECK_(nullHandle)); - } - - // Parse additional attributes in code attribute - cfs->guarantee_more(2, CHECK_(nullHandle)); // code_attributes_count - u2 code_attributes_count = cfs->get_u2_fast(); - - unsigned int calculated_attribute_length = 0; - - if (_major_version > 45 || (_major_version == 45 && _minor_version > 2)) { - calculated_attribute_length = - sizeof(max_stack) + sizeof(max_locals) + sizeof(code_length); - } else { - // max_stack, locals and length are smaller in pre-version 45.2 classes - calculated_attribute_length = sizeof(u1) + sizeof(u1) + sizeof(u2); - } - calculated_attribute_length += - code_length + - sizeof(exception_table_length) + - sizeof(code_attributes_count) + - exception_table_length * - ( sizeof(u2) + // start_pc - sizeof(u2) + // end_pc - sizeof(u2) + // handler_pc - sizeof(u2) ); // catch_type_index - - while (code_attributes_count--) { - cfs->guarantee_more(6, CHECK_(nullHandle)); // code_attribute_name_index, code_attribute_length - u2 code_attribute_name_index = cfs->get_u2_fast(); - u4 code_attribute_length = cfs->get_u4_fast(); - calculated_attribute_length += code_attribute_length + - sizeof(code_attribute_name_index) + - sizeof(code_attribute_length); - check_property(valid_symbol_at(code_attribute_name_index), - "Invalid code attribute name index %u in class file %s", - code_attribute_name_index, - CHECK_(nullHandle)); - if (LoadLineNumberTables && - _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_line_number_table()) { - // Parse and compress line number table - parse_linenumber_table(code_attribute_length, code_length, - &linenumber_table, CHECK_(nullHandle)); - - } else if (LoadLocalVariableTables && - _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_table()) { - // Parse local variable table - if (!lvt_allocated) { - localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, u2, INITIAL_MAX_LVT_NUMBER); - localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, u2*, INITIAL_MAX_LVT_NUMBER); - localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, u2, INITIAL_MAX_LVT_NUMBER); - localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, u2*, INITIAL_MAX_LVT_NUMBER); - lvt_allocated = true; - } - if (lvt_cnt == max_lvt_cnt) { - max_lvt_cnt <<= 1; - localvariable_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt); - localvariable_table_start = REALLOC_RESOURCE_ARRAY(u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt); - } - localvariable_table_start[lvt_cnt] = - parse_localvariable_table(code_length, - max_locals, - code_attribute_length, - &localvariable_table_length[lvt_cnt], - false, // is not LVTT - CHECK_(nullHandle)); - total_lvt_length += localvariable_table_length[lvt_cnt]; - lvt_cnt++; - } else if (LoadLocalVariableTypeTables && - _major_version >= JAVA_1_5_VERSION && - _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_type_table()) { - if (!lvt_allocated) { - localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, u2, INITIAL_MAX_LVT_NUMBER); - localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, u2*, INITIAL_MAX_LVT_NUMBER); - localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, u2, INITIAL_MAX_LVT_NUMBER); - localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, u2*, INITIAL_MAX_LVT_NUMBER); - lvt_allocated = true; - } - // Parse local variable type table - if (lvtt_cnt == max_lvtt_cnt) { - max_lvtt_cnt <<= 1; - localvariable_type_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt); - localvariable_type_table_start = REALLOC_RESOURCE_ARRAY(u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt); - } - localvariable_type_table_start[lvtt_cnt] = - parse_localvariable_table(code_length, - max_locals, - code_attribute_length, - &localvariable_type_table_length[lvtt_cnt], - true, // is LVTT - CHECK_(nullHandle)); - lvtt_cnt++; - } else if (_major_version >= Verifier::STACKMAP_ATTRIBUTE_MAJOR_VERSION && - _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_stack_map_table()) { - // Stack map is only needed by the new verifier in JDK1.5. - if (parsed_stackmap_attribute) { - classfile_parse_error("Multiple StackMapTable attributes in class file %s", CHECK_(nullHandle)); - } - stackmap_data = parse_stackmap_table(code_attribute_length, CHECK_(nullHandle)); - stackmap_data_length = code_attribute_length; - parsed_stackmap_attribute = true; - } else { - // Skip unknown attributes - cfs->skip_u1(code_attribute_length, CHECK_(nullHandle)); - } - } - // check method attribute length - if (_need_verify) { - guarantee_property(method_attribute_length == calculated_attribute_length, - "Code segment has wrong length in class file %s", CHECK_(nullHandle)); - } - } else if (method_attribute_name == vmSymbols::tag_exceptions()) { - // Parse Exceptions attribute - if (parsed_checked_exceptions_attribute) { - classfile_parse_error("Multiple Exceptions attributes in class file %s", CHECK_(nullHandle)); - } - parsed_checked_exceptions_attribute = true; - checked_exceptions_start = - parse_checked_exceptions(&checked_exceptions_length, - method_attribute_length, - CHECK_(nullHandle)); - } else if (method_attribute_name == vmSymbols::tag_method_parameters()) { - // reject multiple method parameters - if (method_parameters_seen) { - classfile_parse_error("Multiple MethodParameters attributes in class file %s", CHECK_(nullHandle)); - } - method_parameters_seen = true; - method_parameters_length = cfs->get_u1_fast(); - if (method_attribute_length != (method_parameters_length * 4u) + 1u) { - classfile_parse_error( - "Invalid MethodParameters method attribute length %u in class file", - method_attribute_length, CHECK_(nullHandle)); - } - method_parameters_data = cfs->get_u1_buffer(); - cfs->skip_u2_fast(method_parameters_length); - cfs->skip_u2_fast(method_parameters_length); - // ignore this attribute if it cannot be reflected - if (!SystemDictionary::Parameter_klass_loaded()) - method_parameters_length = 0; - } else if (method_attribute_name == vmSymbols::tag_synthetic()) { - if (method_attribute_length != 0) { - classfile_parse_error( - "Invalid Synthetic method attribute length %u in class file %s", - method_attribute_length, CHECK_(nullHandle)); - } - // Should we check that there hasn't already been a synthetic attribute? - access_flags.set_is_synthetic(); - } else if (method_attribute_name == vmSymbols::tag_deprecated()) { // 4276120 - if (method_attribute_length != 0) { - classfile_parse_error( - "Invalid Deprecated method attribute length %u in class file %s", - method_attribute_length, CHECK_(nullHandle)); - } - } else if (_major_version >= JAVA_1_5_VERSION) { - if (method_attribute_name == vmSymbols::tag_signature()) { - if (method_attribute_length != 2) { - classfile_parse_error( - "Invalid Signature attribute length %u in class file %s", - method_attribute_length, CHECK_(nullHandle)); - } - generic_signature_index = parse_generic_signature_attribute(CHECK_(nullHandle)); - } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) { - if (runtime_visible_annotations != NULL) { - classfile_parse_error( - "Multiple RuntimeVisibleAnnotations attributes for method in class file %s", CHECK_(nullHandle)); - } - runtime_visible_annotations_length = method_attribute_length; - runtime_visible_annotations = cfs->get_u1_buffer(); - assert(runtime_visible_annotations != NULL, "null visible annotations"); - parse_annotations(runtime_visible_annotations, - runtime_visible_annotations_length, &parsed_annotations, - CHECK_(nullHandle)); - cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); - } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { - if (runtime_invisible_annotations_exists) { - classfile_parse_error( - "Multiple RuntimeInvisibleAnnotations attributes for method in class file %s", CHECK_(nullHandle)); - } - runtime_invisible_annotations_exists = true; - if (PreserveAllAnnotations) { - runtime_invisible_annotations_length = method_attribute_length; - runtime_invisible_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_annotations != NULL, "null invisible annotations"); - } - cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); - } else if (method_attribute_name == vmSymbols::tag_runtime_visible_parameter_annotations()) { - if (runtime_visible_parameter_annotations != NULL) { - classfile_parse_error( - "Multiple RuntimeVisibleParameterAnnotations attributes for method in class file %s", CHECK_(nullHandle)); - } - runtime_visible_parameter_annotations_length = method_attribute_length; - runtime_visible_parameter_annotations = cfs->get_u1_buffer(); - assert(runtime_visible_parameter_annotations != NULL, "null visible parameter annotations"); - cfs->skip_u1(runtime_visible_parameter_annotations_length, CHECK_(nullHandle)); - } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_parameter_annotations()) { - if (runtime_invisible_parameter_annotations_exists) { - classfile_parse_error( - "Multiple RuntimeInvisibleParameterAnnotations attributes for method in class file %s", CHECK_(nullHandle)); - } - runtime_invisible_parameter_annotations_exists = true; - if (PreserveAllAnnotations) { - runtime_invisible_parameter_annotations_length = method_attribute_length; - runtime_invisible_parameter_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_parameter_annotations != NULL, "null invisible parameter annotations"); - } - cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); - } else if (method_attribute_name == vmSymbols::tag_annotation_default()) { - if (annotation_default != NULL) { - classfile_parse_error( - "Multiple AnnotationDefault attributes for method in class file %s", - CHECK_(nullHandle)); - } - annotation_default_length = method_attribute_length; - annotation_default = cfs->get_u1_buffer(); - assert(annotation_default != NULL, "null annotation default"); - cfs->skip_u1(annotation_default_length, CHECK_(nullHandle)); - } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { - if (runtime_visible_type_annotations != NULL) { - classfile_parse_error( - "Multiple RuntimeVisibleTypeAnnotations attributes for method in class file %s", - CHECK_(nullHandle)); - } - runtime_visible_type_annotations_length = method_attribute_length; - runtime_visible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); - // No need for the VM to parse Type annotations - cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle)); - } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { - if (runtime_invisible_type_annotations_exists) { - classfile_parse_error( - "Multiple RuntimeInvisibleTypeAnnotations attributes for method in class file %s", - CHECK_(nullHandle)); - } else { - runtime_invisible_type_annotations_exists = true; - } - if (PreserveAllAnnotations) { - runtime_invisible_type_annotations_length = method_attribute_length; - runtime_invisible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); - } - cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); - } else { - // Skip unknown attributes - cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); - } - } else { - // Skip unknown attributes - cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); - } - } - - if (linenumber_table != NULL) { - linenumber_table->write_terminator(); - linenumber_table_length = linenumber_table->position(); - } - - // Make sure there's at least one Code attribute in non-native/non-abstract method - if (_need_verify) { - guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute, - "Absent Code attribute in method that is not native or abstract in class file %s", CHECK_(nullHandle)); - } - - // All sizing information for a Method* is finally available, now create it - InlineTableSizes sizes( - total_lvt_length, - linenumber_table_length, - exception_table_length, - checked_exceptions_length, - method_parameters_length, - generic_signature_index, - runtime_visible_annotations_length + - runtime_invisible_annotations_length, - runtime_visible_parameter_annotations_length + - runtime_invisible_parameter_annotations_length, - runtime_visible_type_annotations_length + - runtime_invisible_type_annotations_length, - annotation_default_length, - 0); - - Method* m = Method::allocate( - _loader_data, code_length, access_flags, &sizes, - ConstMethod::NORMAL, CHECK_(nullHandle)); - - ClassLoadingService::add_class_method_size(m->size()*HeapWordSize); - - // Fill in information from fixed part (access_flags already set) - m->set_constants(_cp); - m->set_name_index(name_index); - m->set_signature_index(signature_index); -#ifdef CC_INTERP - // hmm is there a gc issue here?? - ResultTypeFinder rtf(_cp->symbol_at(signature_index)); - m->set_result_index(rtf.type()); -#endif - - if (args_size >= 0) { - m->set_size_of_parameters(args_size); - } else { - m->compute_size_of_parameters(THREAD); - } -#ifdef ASSERT - if (args_size >= 0) { - m->compute_size_of_parameters(THREAD); - assert(args_size == m->size_of_parameters(), ""); - } -#endif - - // Fill in code attribute information - m->set_max_stack(max_stack); - m->set_max_locals(max_locals); - if (stackmap_data != NULL) { - m->constMethod()->copy_stackmap_data(_loader_data, stackmap_data, - stackmap_data_length, CHECK_NULL); - } - - // Copy byte codes - m->set_code(code_start); - - // Copy line number table - if (linenumber_table != NULL) { - memcpy(m->compressed_linenumber_table(), - linenumber_table->buffer(), linenumber_table_length); - } - - // Copy exception table - if (exception_table_length > 0) { - int size = - exception_table_length * sizeof(ExceptionTableElement) / sizeof(u2); - copy_u2_with_conversion((u2*) m->exception_table_start(), - exception_table_start, size); - } - - // Copy method parameters - if (method_parameters_length > 0) { - MethodParametersElement* elem = m->constMethod()->method_parameters_start(); - for (int i = 0; i < method_parameters_length; i++) { - elem[i].name_cp_index = Bytes::get_Java_u2(method_parameters_data); - method_parameters_data += 2; - elem[i].flags = Bytes::get_Java_u2(method_parameters_data); - method_parameters_data += 2; - } - } - - // Copy checked exceptions - if (checked_exceptions_length > 0) { - int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); - copy_u2_with_conversion((u2*) m->checked_exceptions_start(), checked_exceptions_start, size); - } - - // Copy class file LVT's/LVTT's into the HotSpot internal LVT. - if (total_lvt_length > 0) { - promoted_flags->set_has_localvariable_table(); - copy_localvariable_table(m->constMethod(), lvt_cnt, - localvariable_table_length, - localvariable_table_start, - lvtt_cnt, - localvariable_type_table_length, - localvariable_type_table_start, CHECK_NULL); - } - - if (parsed_annotations.has_any_annotations()) - parsed_annotations.apply_to(m); - - // Copy annotations - copy_method_annotations(m->constMethod(), - runtime_visible_annotations, - runtime_visible_annotations_length, - runtime_invisible_annotations, - runtime_invisible_annotations_length, - runtime_visible_parameter_annotations, - runtime_visible_parameter_annotations_length, - runtime_invisible_parameter_annotations, - runtime_invisible_parameter_annotations_length, - runtime_visible_type_annotations, - runtime_visible_type_annotations_length, - runtime_invisible_type_annotations, - runtime_invisible_type_annotations_length, - annotation_default, - annotation_default_length, - CHECK_NULL); - - if (name == vmSymbols::finalize_method_name() && - signature == vmSymbols::void_method_signature()) { - if (m->is_empty_method()) { - _has_empty_finalizer = true; - } else { - _has_finalizer = true; - } - } - if (name == vmSymbols::object_initializer_name() && - signature == vmSymbols::void_method_signature() && - m->is_vanilla_constructor()) { - _has_vanilla_constructor = true; - } - - NOT_PRODUCT(m->verify()); - return m; -} - - -// The promoted_flags parameter is used to pass relevant access_flags -// from the methods back up to the containing klass. These flag values -// are added to klass's access_flags. - -Array* ClassFileParser::parse_methods(bool is_interface, - AccessFlags* promoted_flags, - bool* has_final_method, - bool* has_default_methods, - TRAPS) { - ClassFileStream* cfs = stream(); - cfs->guarantee_more(2, CHECK_NULL); // length - u2 length = cfs->get_u2_fast(); - if (length == 0) { - _methods = Universe::the_empty_method_array(); - } else { - _methods = MetadataFactory::new_array(_loader_data, length, NULL, CHECK_NULL); - - HandleMark hm(THREAD); - for (int index = 0; index < length; index++) { - methodHandle method = parse_method(is_interface, - promoted_flags, - CHECK_NULL); - - if (method->is_final()) { - *has_final_method = true; - } - if (is_interface && !(*has_default_methods) - && !method->is_abstract() && !method->is_static() - && !method->is_private()) { - // default method - *has_default_methods = true; - } - _methods->at_put(index, method()); - } - - if (_need_verify && length > 1) { - // Check duplicated methods - ResourceMark rm(THREAD); - NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, NameSigHash*, HASH_ROW_SIZE); - initialize_hashtable(names_and_sigs); - bool dup = false; - { - debug_only(No_Safepoint_Verifier nsv;) - for (int i = 0; i < length; i++) { - Method* m = _methods->at(i); - // If no duplicates, add name/signature in hashtable names_and_sigs. - if (!put_after_lookup(m->name(), m->signature(), names_and_sigs)) { - dup = true; - break; - } - } - } - if (dup) { - classfile_parse_error("Duplicate method name&signature in class file %s", - CHECK_NULL); - } - } - } - return _methods; -} - - -intArray* ClassFileParser::sort_methods(Array* methods) { - int length = methods->length(); - // If JVMTI original method ordering or sharing is enabled we have to - // remember the original class file ordering. - // We temporarily use the vtable_index field in the Method* to store the - // class file index, so we can read in after calling qsort. - // Put the method ordering in the shared archive. - if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) { - for (int index = 0; index < length; index++) { - Method* m = methods->at(index); - assert(!m->valid_vtable_index(), "vtable index should not be set"); - m->set_vtable_index(index); - } - } - // Sort method array by ascending method name (for faster lookups & vtable construction) - // Note that the ordering is not alphabetical, see Symbol::fast_compare - Method::sort_methods(methods); - - intArray* method_ordering = NULL; - // If JVMTI original method ordering or sharing is enabled construct int - // array remembering the original ordering - if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) { - method_ordering = new intArray(length); - for (int index = 0; index < length; index++) { - Method* m = methods->at(index); - int old_index = m->vtable_index(); - assert(old_index >= 0 && old_index < length, "invalid method index"); - method_ordering->at_put(index, old_index); - m->set_vtable_index(Method::invalid_vtable_index); - } - } - return method_ordering; -} - -// Parse generic_signature attribute for methods and fields -u2 ClassFileParser::parse_generic_signature_attribute(TRAPS) { - ClassFileStream* cfs = stream(); - cfs->guarantee_more(2, CHECK_0); // generic_signature_index - u2 generic_signature_index = cfs->get_u2_fast(); - check_property( - valid_symbol_at(generic_signature_index), - "Invalid Signature attribute at constant pool index %u in class file %s", - generic_signature_index, CHECK_0); - return generic_signature_index; -} - -void ClassFileParser::parse_classfile_sourcefile_attribute(TRAPS) { - ClassFileStream* cfs = stream(); - cfs->guarantee_more(2, CHECK); // sourcefile_index - u2 sourcefile_index = cfs->get_u2_fast(); - check_property( - valid_symbol_at(sourcefile_index), - "Invalid SourceFile attribute at constant pool index %u in class file %s", - sourcefile_index, CHECK); - set_class_sourcefile_index(sourcefile_index); -} - - - -void ClassFileParser::parse_classfile_source_debug_extension_attribute(int length, TRAPS) { - ClassFileStream* cfs = stream(); - u1* sde_buffer = cfs->get_u1_buffer(); - assert(sde_buffer != NULL, "null sde buffer"); - - // Don't bother storing it if there is no way to retrieve it - if (JvmtiExport::can_get_source_debug_extension()) { - assert((length+1) > length, "Overflow checking"); - u1* sde = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, u1, length+1); - for (int i = 0; i < length; i++) { - sde[i] = sde_buffer[i]; - } - sde[length] = '\0'; - set_class_sde_buffer((char*)sde, length); - } - // Got utf8 string, set stream position forward - cfs->skip_u1(length, CHECK); -} - - -// Inner classes can be static, private or protected (classic VM does this) -#define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC) - -// Return number of classes in the inner classes attribute table -u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start, - bool parsed_enclosingmethod_attribute, - u2 enclosing_method_class_index, - u2 enclosing_method_method_index, - TRAPS) { - ClassFileStream* cfs = stream(); - u1* current_mark = cfs->current(); - u2 length = 0; - if (inner_classes_attribute_start != NULL) { - cfs->set_current(inner_classes_attribute_start); - cfs->guarantee_more(2, CHECK_0); // length - length = cfs->get_u2_fast(); - } - - // 4-tuples of shorts of inner classes data and 2 shorts of enclosing - // method data: - // [inner_class_info_index, - // outer_class_info_index, - // inner_name_index, - // inner_class_access_flags, - // ... - // enclosing_method_class_index, - // enclosing_method_method_index] - int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0); - Array* inner_classes = MetadataFactory::new_array(_loader_data, size, CHECK_0); - _inner_classes = inner_classes; - - int index = 0; - int cp_size = _cp->length(); - cfs->guarantee_more(8 * length, CHECK_0); // 4-tuples of u2 - for (int n = 0; n < length; n++) { - // Inner class index - u2 inner_class_info_index = cfs->get_u2_fast(); - check_property( - inner_class_info_index == 0 || - valid_klass_reference_at(inner_class_info_index), - "inner_class_info_index %u has bad constant type in class file %s", - inner_class_info_index, CHECK_0); - // Outer class index - u2 outer_class_info_index = cfs->get_u2_fast(); - check_property( - outer_class_info_index == 0 || - valid_klass_reference_at(outer_class_info_index), - "outer_class_info_index %u has bad constant type in class file %s", - outer_class_info_index, CHECK_0); - // Inner class name - u2 inner_name_index = cfs->get_u2_fast(); - check_property( - inner_name_index == 0 || valid_symbol_at(inner_name_index), - "inner_name_index %u has bad constant type in class file %s", - inner_name_index, CHECK_0); - if (_need_verify) { - guarantee_property(inner_class_info_index != outer_class_info_index, - "Class is both outer and inner class in class file %s", CHECK_0); - } - // Access flags - AccessFlags inner_access_flags; - jint flags = cfs->get_u2_fast() & RECOGNIZED_INNER_CLASS_MODIFIERS; - if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) { - // Set abstract bit for old class files for backward compatibility - flags |= JVM_ACC_ABSTRACT; - } - verify_legal_class_modifiers(flags, CHECK_0); - inner_access_flags.set_flags(flags); - - inner_classes->at_put(index++, inner_class_info_index); - inner_classes->at_put(index++, outer_class_info_index); - inner_classes->at_put(index++, inner_name_index); - inner_classes->at_put(index++, inner_access_flags.as_short()); - } - - // 4347400: make sure there's no duplicate entry in the classes array - if (_need_verify && _major_version >= JAVA_1_5_VERSION) { - for(int i = 0; i < length * 4; i += 4) { - for(int j = i + 4; j < length * 4; j += 4) { - guarantee_property((inner_classes->at(i) != inner_classes->at(j) || - inner_classes->at(i+1) != inner_classes->at(j+1) || - inner_classes->at(i+2) != inner_classes->at(j+2) || - inner_classes->at(i+3) != inner_classes->at(j+3)), - "Duplicate entry in InnerClasses in class file %s", - CHECK_0); - } - } - } - - // Set EnclosingMethod class and method indexes. - if (parsed_enclosingmethod_attribute) { - inner_classes->at_put(index++, enclosing_method_class_index); - inner_classes->at_put(index++, enclosing_method_method_index); - } - assert(index == size, "wrong size"); - - // Restore buffer's current position. - cfs->set_current(current_mark); - - return length; -} - -void ClassFileParser::parse_classfile_synthetic_attribute(TRAPS) { - set_class_synthetic_flag(true); -} - -void ClassFileParser::parse_classfile_signature_attribute(TRAPS) { - ClassFileStream* cfs = stream(); - u2 signature_index = cfs->get_u2(CHECK); - check_property( - valid_symbol_at(signature_index), - "Invalid constant pool index %u in Signature attribute in class file %s", - signature_index, CHECK); - set_class_generic_signature_index(signature_index); -} - -void ClassFileParser::parse_classfile_bootstrap_methods_attribute(u4 attribute_byte_length, TRAPS) { - ClassFileStream* cfs = stream(); - u1* current_start = cfs->current(); - - guarantee_property(attribute_byte_length >= sizeof(u2), - "Invalid BootstrapMethods attribute length %u in class file %s", - attribute_byte_length, - CHECK); - - cfs->guarantee_more(attribute_byte_length, CHECK); - - int attribute_array_length = cfs->get_u2_fast(); - - guarantee_property(_max_bootstrap_specifier_index < attribute_array_length, - "Short length on BootstrapMethods in class file %s", - CHECK); - - - // The attribute contains a counted array of counted tuples of shorts, - // represending bootstrap specifiers: - // length*{bootstrap_method_index, argument_count*{argument_index}} - int operand_count = (attribute_byte_length - sizeof(u2)) / sizeof(u2); - // operand_count = number of shorts in attr, except for leading length - - // The attribute is copied into a short[] array. - // The array begins with a series of short[2] pairs, one for each tuple. - int index_size = (attribute_array_length * 2); - - Array* operands = MetadataFactory::new_array(_loader_data, index_size + operand_count, CHECK); - - // Eagerly assign operands so they will be deallocated with the constant - // pool if there is an error. - _cp->set_operands(operands); - - int operand_fill_index = index_size; - int cp_size = _cp->length(); - - for (int n = 0; n < attribute_array_length; n++) { - // Store a 32-bit offset into the header of the operand array. - ConstantPool::operand_offset_at_put(operands, n, operand_fill_index); - - // Read a bootstrap specifier. - cfs->guarantee_more(sizeof(u2) * 2, CHECK); // bsm, argc - u2 bootstrap_method_index = cfs->get_u2_fast(); - u2 argument_count = cfs->get_u2_fast(); - check_property( - valid_cp_range(bootstrap_method_index, cp_size) && - _cp->tag_at(bootstrap_method_index).is_method_handle(), - "bootstrap_method_index %u has bad constant type in class file %s", - bootstrap_method_index, - CHECK); - - guarantee_property((operand_fill_index + 1 + argument_count) < operands->length(), - "Invalid BootstrapMethods num_bootstrap_methods or num_bootstrap_arguments value in class file %s", - CHECK); - - operands->at_put(operand_fill_index++, bootstrap_method_index); - operands->at_put(operand_fill_index++, argument_count); - - cfs->guarantee_more(sizeof(u2) * argument_count, CHECK); // argv[argc] - for (int j = 0; j < argument_count; j++) { - u2 argument_index = cfs->get_u2_fast(); - check_property( - valid_cp_range(argument_index, cp_size) && - _cp->tag_at(argument_index).is_loadable_constant(), - "argument_index %u has bad constant type in class file %s", - argument_index, - CHECK); - operands->at_put(operand_fill_index++, argument_index); - } - } - - u1* current_end = cfs->current(); - guarantee_property(current_end == current_start + attribute_byte_length, - "Bad length on BootstrapMethods in class file %s", - CHECK); -} - -void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotationCollector* parsed_annotations, - TRAPS) { - ClassFileStream* cfs = stream(); - // Set inner classes attribute to default sentinel - _inner_classes = Universe::the_empty_short_array(); - cfs->guarantee_more(2, CHECK); // attributes_count - u2 attributes_count = cfs->get_u2_fast(); - bool parsed_sourcefile_attribute = false; - bool parsed_innerclasses_attribute = false; - bool parsed_enclosingmethod_attribute = false; - bool parsed_bootstrap_methods_attribute = false; - u1* runtime_visible_annotations = NULL; - int runtime_visible_annotations_length = 0; - u1* runtime_invisible_annotations = NULL; - int runtime_invisible_annotations_length = 0; - u1* runtime_visible_type_annotations = NULL; - int runtime_visible_type_annotations_length = 0; - u1* runtime_invisible_type_annotations = NULL; - int runtime_invisible_type_annotations_length = 0; - bool runtime_invisible_type_annotations_exists = false; - bool runtime_invisible_annotations_exists = false; - bool parsed_source_debug_ext_annotations_exist = false; - u1* inner_classes_attribute_start = NULL; - u4 inner_classes_attribute_length = 0; - u2 enclosing_method_class_index = 0; - u2 enclosing_method_method_index = 0; - // Iterate over attributes - while (attributes_count--) { - cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length - u2 attribute_name_index = cfs->get_u2_fast(); - u4 attribute_length = cfs->get_u4_fast(); - check_property( - valid_symbol_at(attribute_name_index), - "Attribute name has bad constant pool index %u in class file %s", - attribute_name_index, CHECK); - Symbol* tag = _cp->symbol_at(attribute_name_index); - if (tag == vmSymbols::tag_source_file()) { - // Check for SourceFile tag - if (_need_verify) { - guarantee_property(attribute_length == 2, "Wrong SourceFile attribute length in class file %s", CHECK); - } - if (parsed_sourcefile_attribute) { - classfile_parse_error("Multiple SourceFile attributes in class file %s", CHECK); - } else { - parsed_sourcefile_attribute = true; - } - parse_classfile_sourcefile_attribute(CHECK); - } else if (tag == vmSymbols::tag_source_debug_extension()) { - // Check for SourceDebugExtension tag - if (parsed_source_debug_ext_annotations_exist) { - classfile_parse_error( - "Multiple SourceDebugExtension attributes in class file %s", CHECK); - } - parsed_source_debug_ext_annotations_exist = true; - parse_classfile_source_debug_extension_attribute((int)attribute_length, CHECK); - } else if (tag == vmSymbols::tag_inner_classes()) { - // Check for InnerClasses tag - if (parsed_innerclasses_attribute) { - classfile_parse_error("Multiple InnerClasses attributes in class file %s", CHECK); - } else { - parsed_innerclasses_attribute = true; - } - inner_classes_attribute_start = cfs->get_u1_buffer(); - inner_classes_attribute_length = attribute_length; - cfs->skip_u1(inner_classes_attribute_length, CHECK); - } else if (tag == vmSymbols::tag_synthetic()) { - // Check for Synthetic tag - // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec - if (attribute_length != 0) { - classfile_parse_error( - "Invalid Synthetic classfile attribute length %u in class file %s", - attribute_length, CHECK); - } - parse_classfile_synthetic_attribute(CHECK); - } else if (tag == vmSymbols::tag_deprecated()) { - // Check for Deprecatd tag - 4276120 - if (attribute_length != 0) { - classfile_parse_error( - "Invalid Deprecated classfile attribute length %u in class file %s", - attribute_length, CHECK); - } - } else if (_major_version >= JAVA_1_5_VERSION) { - if (tag == vmSymbols::tag_signature()) { - if (attribute_length != 2) { - classfile_parse_error( - "Wrong Signature attribute length %u in class file %s", - attribute_length, CHECK); - } - parse_classfile_signature_attribute(CHECK); - } else if (tag == vmSymbols::tag_runtime_visible_annotations()) { - if (runtime_visible_annotations != NULL) { - classfile_parse_error( - "Multiple RuntimeVisibleAnnotations attributes in class file %s", CHECK); - } - runtime_visible_annotations_length = attribute_length; - runtime_visible_annotations = cfs->get_u1_buffer(); - assert(runtime_visible_annotations != NULL, "null visible annotations"); - parse_annotations(runtime_visible_annotations, - runtime_visible_annotations_length, - parsed_annotations, - CHECK); - cfs->skip_u1(runtime_visible_annotations_length, CHECK); - } else if (tag == vmSymbols::tag_runtime_invisible_annotations()) { - if (runtime_invisible_annotations_exists) { - classfile_parse_error( - "Multiple RuntimeInvisibleAnnotations attributes in class file %s", CHECK); - } - runtime_invisible_annotations_exists = true; - if (PreserveAllAnnotations) { - runtime_invisible_annotations_length = attribute_length; - runtime_invisible_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_annotations != NULL, "null invisible annotations"); - } - cfs->skip_u1(attribute_length, CHECK); - } else if (tag == vmSymbols::tag_enclosing_method()) { - if (parsed_enclosingmethod_attribute) { - classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK); - } else { - parsed_enclosingmethod_attribute = true; - } - guarantee_property(attribute_length == 4, - "Wrong EnclosingMethod attribute length %u in class file %s", - attribute_length, CHECK); - cfs->guarantee_more(4, CHECK); // class_index, method_index - enclosing_method_class_index = cfs->get_u2_fast(); - enclosing_method_method_index = cfs->get_u2_fast(); - if (enclosing_method_class_index == 0) { - classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK); - } - // Validate the constant pool indices and types - check_property(valid_klass_reference_at(enclosing_method_class_index), - "Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK); - if (enclosing_method_method_index != 0 && - (!_cp->is_within_bounds(enclosing_method_method_index) || - !_cp->tag_at(enclosing_method_method_index).is_name_and_type())) { - classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK); - } - } else if (tag == vmSymbols::tag_bootstrap_methods() && - _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { - if (parsed_bootstrap_methods_attribute) - classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK); - parsed_bootstrap_methods_attribute = true; - parse_classfile_bootstrap_methods_attribute(attribute_length, CHECK); - } else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) { - if (runtime_visible_type_annotations != NULL) { - classfile_parse_error( - "Multiple RuntimeVisibleTypeAnnotations attributes in class file %s", CHECK); - } - runtime_visible_type_annotations_length = attribute_length; - runtime_visible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); - // No need for the VM to parse Type annotations - cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); - } else if (tag == vmSymbols::tag_runtime_invisible_type_annotations()) { - if (runtime_invisible_type_annotations_exists) { - classfile_parse_error( - "Multiple RuntimeInvisibleTypeAnnotations attributes in class file %s", CHECK); - } else { - runtime_invisible_type_annotations_exists = true; - } - if (PreserveAllAnnotations) { - runtime_invisible_type_annotations_length = attribute_length; - runtime_invisible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); - } - cfs->skip_u1(attribute_length, CHECK); - } else { - // Unknown attribute - cfs->skip_u1(attribute_length, CHECK); - } - } else { - // Unknown attribute - cfs->skip_u1(attribute_length, CHECK); - } - } - _annotations = assemble_annotations(runtime_visible_annotations, - runtime_visible_annotations_length, - runtime_invisible_annotations, - runtime_invisible_annotations_length, - CHECK); - _type_annotations = assemble_annotations(runtime_visible_type_annotations, - runtime_visible_type_annotations_length, - runtime_invisible_type_annotations, - runtime_invisible_type_annotations_length, - CHECK); - - if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) { - u2 num_of_classes = parse_classfile_inner_classes_attribute( - inner_classes_attribute_start, - parsed_innerclasses_attribute, - enclosing_method_class_index, - enclosing_method_method_index, - CHECK); - if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) { - guarantee_property( - inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes, - "Wrong InnerClasses attribute length in class file %s", CHECK); - } - } - - if (_max_bootstrap_specifier_index >= 0) { - guarantee_property(parsed_bootstrap_methods_attribute, - "Missing BootstrapMethods attribute in class file %s", CHECK); - } -} - -void ClassFileParser::apply_parsed_class_attributes(instanceKlassHandle k) { - if (_synthetic_flag) - k->set_is_synthetic(); - if (_sourcefile_index != 0) { - k->set_source_file_name_index(_sourcefile_index); - } - if (_generic_signature_index != 0) { - k->set_generic_signature_index(_generic_signature_index); - } - if (_sde_buffer != NULL) { - k->set_source_debug_extension(_sde_buffer, _sde_length); - } -} - -// Transfer ownership of metadata allocated to the InstanceKlass. -void ClassFileParser::apply_parsed_class_metadata( - instanceKlassHandle this_klass, - int java_fields_count, TRAPS) { - // Assign annotations if needed - if (_annotations != NULL || _type_annotations != NULL || - _fields_annotations != NULL || _fields_type_annotations != NULL) { - Annotations* annotations = Annotations::allocate(_loader_data, CHECK); - annotations->set_class_annotations(_annotations); - annotations->set_class_type_annotations(_type_annotations); - annotations->set_fields_annotations(_fields_annotations); - annotations->set_fields_type_annotations(_fields_type_annotations); - this_klass->set_annotations(annotations); - } - - _cp->set_pool_holder(this_klass()); - this_klass->set_constants(_cp); - this_klass->set_fields(_fields, java_fields_count); - this_klass->set_methods(_methods); - this_klass->set_inner_classes(_inner_classes); - this_klass->set_local_interfaces(_local_interfaces); - this_klass->set_transitive_interfaces(_transitive_interfaces); - - // Clear out these fields so they don't get deallocated by the destructor - clear_class_metadata(); -} - -AnnotationArray* ClassFileParser::assemble_annotations(u1* runtime_visible_annotations, - int runtime_visible_annotations_length, - u1* runtime_invisible_annotations, - int runtime_invisible_annotations_length, TRAPS) { - AnnotationArray* annotations = NULL; - if (runtime_visible_annotations != NULL || - runtime_invisible_annotations != NULL) { - annotations = MetadataFactory::new_array(_loader_data, - runtime_visible_annotations_length + - runtime_invisible_annotations_length, - CHECK_(annotations)); - if (runtime_visible_annotations != NULL) { - for (int i = 0; i < runtime_visible_annotations_length; i++) { - annotations->at_put(i, runtime_visible_annotations[i]); - } - } - if (runtime_invisible_annotations != NULL) { - for (int i = 0; i < runtime_invisible_annotations_length; i++) { - int append = runtime_visible_annotations_length+i; - annotations->at_put(append, runtime_invisible_annotations[i]); - } - } - } - return annotations; -} - -instanceKlassHandle ClassFileParser::parse_super_class(int super_class_index, - TRAPS) { - instanceKlassHandle super_klass; - if (super_class_index == 0) { - check_property(_class_name == vmSymbols::java_lang_Object(), - "Invalid superclass index %u in class file %s", - super_class_index, - CHECK_NULL); - } else { - check_property(valid_klass_reference_at(super_class_index), - "Invalid superclass index %u in class file %s", - super_class_index, - CHECK_NULL); - // The class name should be legal because it is checked when parsing constant pool. - // However, make sure it is not an array type. - bool is_array = false; - if (_cp->tag_at(super_class_index).is_klass()) { - super_klass = instanceKlassHandle(THREAD, _cp->resolved_klass_at(super_class_index)); - if (_need_verify) - is_array = super_klass->oop_is_array(); - } else if (_need_verify) { - is_array = (_cp->klass_name_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY); - } - if (_need_verify) { - guarantee_property(!is_array, - "Bad superclass name in class file %s", CHECK_NULL); - } - } - return super_klass; -} - - -// Values needed for oopmap and InstanceKlass creation -class FieldLayoutInfo : public StackObj { - public: - int* nonstatic_oop_offsets; - unsigned int* nonstatic_oop_counts; - unsigned int nonstatic_oop_map_count; - unsigned int total_oop_map_count; - int instance_size; - int nonstatic_field_size; - int static_field_size; - bool has_nonstatic_fields; -}; - -// Layout fields and fill in FieldLayoutInfo. Could use more refactoring! -void ClassFileParser::layout_fields(Handle class_loader, - FieldAllocationCount* fac, - ClassAnnotationCollector* parsed_annotations, - FieldLayoutInfo* info, - TRAPS) { - - // Field size and offset computation - int nonstatic_field_size = _super_klass() == NULL ? 0 : _super_klass()->nonstatic_field_size(); - int next_static_oop_offset; - int next_static_double_offset; - int next_static_word_offset; - int next_static_short_offset; - int next_static_byte_offset; - int next_nonstatic_oop_offset; - int next_nonstatic_double_offset; - int next_nonstatic_word_offset; - int next_nonstatic_short_offset; - int next_nonstatic_byte_offset; - int first_nonstatic_oop_offset; - int next_nonstatic_field_offset; - int next_nonstatic_padded_offset; - - // Count the contended fields by type. - // - // We ignore static fields, because @Contended is not supported for them. - // The layout code below will also ignore the static fields. - int nonstatic_contended_count = 0; - FieldAllocationCount fac_contended; - for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { - FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); - if (fs.is_contended()) { - fac_contended.count[atype]++; - if (!fs.access_flags().is_static()) { - nonstatic_contended_count++; - } - } - } - - - // Calculate the starting byte offsets - next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields(); - next_static_double_offset = next_static_oop_offset + - ((fac->count[STATIC_OOP]) * heapOopSize); - if ( fac->count[STATIC_DOUBLE] && - (Universe::field_type_should_be_aligned(T_DOUBLE) || - Universe::field_type_should_be_aligned(T_LONG)) ) { - next_static_double_offset = align_size_up(next_static_double_offset, BytesPerLong); - } - - next_static_word_offset = next_static_double_offset + - ((fac->count[STATIC_DOUBLE]) * BytesPerLong); - next_static_short_offset = next_static_word_offset + - ((fac->count[STATIC_WORD]) * BytesPerInt); - next_static_byte_offset = next_static_short_offset + - ((fac->count[STATIC_SHORT]) * BytesPerShort); - - int nonstatic_fields_start = instanceOopDesc::base_offset_in_bytes() + - nonstatic_field_size * heapOopSize; - - next_nonstatic_field_offset = nonstatic_fields_start; - - bool is_contended_class = parsed_annotations->is_contended(); - - // Class is contended, pad before all the fields - if (is_contended_class) { - next_nonstatic_field_offset += ContendedPaddingWidth; - } - - // Compute the non-contended fields count. - // The packing code below relies on these counts to determine if some field - // can be squeezed into the alignment gap. Contended fields are obviously - // exempt from that. - unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE]; - unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD]; - unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT]; - unsigned int nonstatic_byte_count = fac->count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE]; - unsigned int nonstatic_oop_count = fac->count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP]; - - // Total non-static fields count, including every contended field - unsigned int nonstatic_fields_count = fac->count[NONSTATIC_DOUBLE] + fac->count[NONSTATIC_WORD] + - fac->count[NONSTATIC_SHORT] + fac->count[NONSTATIC_BYTE] + - fac->count[NONSTATIC_OOP]; - - bool super_has_nonstatic_fields = - (_super_klass() != NULL && _super_klass->has_nonstatic_fields()); - bool has_nonstatic_fields = super_has_nonstatic_fields || (nonstatic_fields_count != 0); - - - // Prepare list of oops for oop map generation. - // - // "offset" and "count" lists are describing the set of contiguous oop - // regions. offset[i] is the start of the i-th region, which then has - // count[i] oops following. Before we know how many regions are required, - // we pessimistically allocate the maps to fit all the oops into the - // distinct regions. - // - // TODO: We add +1 to always allocate non-zero resource arrays; we need - // to figure out if we still need to do this. - int* nonstatic_oop_offsets; - unsigned int* nonstatic_oop_counts; - unsigned int nonstatic_oop_map_count = 0; - unsigned int max_nonstatic_oop_maps = fac->count[NONSTATIC_OOP] + 1; - - nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, int, max_nonstatic_oop_maps); - nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, unsigned int, max_nonstatic_oop_maps); - - first_nonstatic_oop_offset = 0; // will be set for first oop field - - bool compact_fields = CompactFields; - int allocation_style = FieldsAllocationStyle; - if( allocation_style < 0 || allocation_style > 2 ) { // Out of range? - assert(false, "0 <= FieldsAllocationStyle <= 2"); - allocation_style = 1; // Optimistic - } - - // The next classes have predefined hard-coded fields offsets - // (see in JavaClasses::compute_hard_coded_offsets()). - // Use default fields allocation order for them. - if( (allocation_style != 0 || compact_fields ) && class_loader.is_null() && - (_class_name == vmSymbols::java_lang_AssertionStatusDirectives() || - _class_name == vmSymbols::java_lang_Class() || - _class_name == vmSymbols::java_lang_ClassLoader() || - _class_name == vmSymbols::java_lang_ref_Reference() || - _class_name == vmSymbols::java_lang_ref_SoftReference() || - _class_name == vmSymbols::java_lang_StackTraceElement() || - _class_name == vmSymbols::java_lang_String() || - _class_name == vmSymbols::java_lang_Throwable() || - _class_name == vmSymbols::java_lang_Boolean() || - _class_name == vmSymbols::java_lang_Character() || - _class_name == vmSymbols::java_lang_Float() || - _class_name == vmSymbols::java_lang_Double() || - _class_name == vmSymbols::java_lang_Byte() || - _class_name == vmSymbols::java_lang_Short() || - _class_name == vmSymbols::java_lang_Integer() || - _class_name == vmSymbols::java_lang_Long())) { - allocation_style = 0; // Allocate oops first - compact_fields = false; // Don't compact fields - } - - // Rearrange fields for a given allocation style - if( allocation_style == 0 ) { - // Fields order: oops, longs/doubles, ints, shorts/chars, bytes, padded fields - next_nonstatic_oop_offset = next_nonstatic_field_offset; - next_nonstatic_double_offset = next_nonstatic_oop_offset + - (nonstatic_oop_count * heapOopSize); - } else if( allocation_style == 1 ) { - // Fields order: longs/doubles, ints, shorts/chars, bytes, oops, padded fields - next_nonstatic_double_offset = next_nonstatic_field_offset; - } else if( allocation_style == 2 ) { - // Fields allocation: oops fields in super and sub classes are together. - if( nonstatic_field_size > 0 && _super_klass() != NULL && - _super_klass->nonstatic_oop_map_size() > 0 ) { - unsigned int map_count = _super_klass->nonstatic_oop_map_count(); - OopMapBlock* first_map = _super_klass->start_of_nonstatic_oop_maps(); - OopMapBlock* last_map = first_map + map_count - 1; - int next_offset = last_map->offset() + (last_map->count() * heapOopSize); - if (next_offset == next_nonstatic_field_offset) { - allocation_style = 0; // allocate oops first - next_nonstatic_oop_offset = next_nonstatic_field_offset; - next_nonstatic_double_offset = next_nonstatic_oop_offset + - (nonstatic_oop_count * heapOopSize); - } - } - if( allocation_style == 2 ) { - allocation_style = 1; // allocate oops last - next_nonstatic_double_offset = next_nonstatic_field_offset; - } - } else { - ShouldNotReachHere(); - } - - int nonstatic_oop_space_count = 0; - int nonstatic_word_space_count = 0; - int nonstatic_short_space_count = 0; - int nonstatic_byte_space_count = 0; - int nonstatic_oop_space_offset; - int nonstatic_word_space_offset; - int nonstatic_short_space_offset; - int nonstatic_byte_space_offset; - - // Try to squeeze some of the fields into the gaps due to - // long/double alignment. - if( nonstatic_double_count > 0 ) { - int offset = next_nonstatic_double_offset; - next_nonstatic_double_offset = align_size_up(offset, BytesPerLong); - if( compact_fields && offset != next_nonstatic_double_offset ) { - // Allocate available fields into the gap before double field. - int length = next_nonstatic_double_offset - offset; - assert(length == BytesPerInt, ""); - nonstatic_word_space_offset = offset; - if( nonstatic_word_count > 0 ) { - nonstatic_word_count -= 1; - nonstatic_word_space_count = 1; // Only one will fit - length -= BytesPerInt; - offset += BytesPerInt; - } - nonstatic_short_space_offset = offset; - while( length >= BytesPerShort && nonstatic_short_count > 0 ) { - nonstatic_short_count -= 1; - nonstatic_short_space_count += 1; - length -= BytesPerShort; - offset += BytesPerShort; - } - nonstatic_byte_space_offset = offset; - while( length > 0 && nonstatic_byte_count > 0 ) { - nonstatic_byte_count -= 1; - nonstatic_byte_space_count += 1; - length -= 1; - } - // Allocate oop field in the gap if there are no other fields for that. - nonstatic_oop_space_offset = offset; - if( length >= heapOopSize && nonstatic_oop_count > 0 && - allocation_style != 0 ) { // when oop fields not first - nonstatic_oop_count -= 1; - nonstatic_oop_space_count = 1; // Only one will fit - length -= heapOopSize; - offset += heapOopSize; - } - } - } - - next_nonstatic_word_offset = next_nonstatic_double_offset + - (nonstatic_double_count * BytesPerLong); - next_nonstatic_short_offset = next_nonstatic_word_offset + - (nonstatic_word_count * BytesPerInt); - next_nonstatic_byte_offset = next_nonstatic_short_offset + - (nonstatic_short_count * BytesPerShort); - next_nonstatic_padded_offset = next_nonstatic_byte_offset + - nonstatic_byte_count; - - // let oops jump before padding with this allocation style - if( allocation_style == 1 ) { - next_nonstatic_oop_offset = next_nonstatic_padded_offset; - if( nonstatic_oop_count > 0 ) { - next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize); - } - next_nonstatic_padded_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize); - } - - // Iterate over fields again and compute correct offsets. - // The field allocation type was temporarily stored in the offset slot. - // oop fields are located before non-oop fields (static and non-static). - for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { - - // skip already laid out fields - if (fs.is_offset_set()) continue; - - // contended instance fields are handled below - if (fs.is_contended() && !fs.access_flags().is_static()) continue; - - int real_offset; - FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); - - // pack the rest of the fields - switch (atype) { - case STATIC_OOP: - real_offset = next_static_oop_offset; - next_static_oop_offset += heapOopSize; - break; - case STATIC_BYTE: - real_offset = next_static_byte_offset; - next_static_byte_offset += 1; - break; - case STATIC_SHORT: - real_offset = next_static_short_offset; - next_static_short_offset += BytesPerShort; - break; - case STATIC_WORD: - real_offset = next_static_word_offset; - next_static_word_offset += BytesPerInt; - break; - case STATIC_DOUBLE: - real_offset = next_static_double_offset; - next_static_double_offset += BytesPerLong; - break; - case NONSTATIC_OOP: - if( nonstatic_oop_space_count > 0 ) { - real_offset = nonstatic_oop_space_offset; - nonstatic_oop_space_offset += heapOopSize; - nonstatic_oop_space_count -= 1; - } else { - real_offset = next_nonstatic_oop_offset; - next_nonstatic_oop_offset += heapOopSize; - } - // Update oop maps - if( nonstatic_oop_map_count > 0 && - nonstatic_oop_offsets[nonstatic_oop_map_count - 1] == - real_offset - - int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) * - heapOopSize ) { - // Extend current oop map - assert(nonstatic_oop_map_count - 1 < max_nonstatic_oop_maps, "range check"); - nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1; - } else { - // Create new oop map - assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check"); - nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset; - nonstatic_oop_counts [nonstatic_oop_map_count] = 1; - nonstatic_oop_map_count += 1; - if( first_nonstatic_oop_offset == 0 ) { // Undefined - first_nonstatic_oop_offset = real_offset; - } - } - break; - case NONSTATIC_BYTE: - if( nonstatic_byte_space_count > 0 ) { - real_offset = nonstatic_byte_space_offset; - nonstatic_byte_space_offset += 1; - nonstatic_byte_space_count -= 1; - } else { - real_offset = next_nonstatic_byte_offset; - next_nonstatic_byte_offset += 1; - } - break; - case NONSTATIC_SHORT: - if( nonstatic_short_space_count > 0 ) { - real_offset = nonstatic_short_space_offset; - nonstatic_short_space_offset += BytesPerShort; - nonstatic_short_space_count -= 1; - } else { - real_offset = next_nonstatic_short_offset; - next_nonstatic_short_offset += BytesPerShort; - } - break; - case NONSTATIC_WORD: - if( nonstatic_word_space_count > 0 ) { - real_offset = nonstatic_word_space_offset; - nonstatic_word_space_offset += BytesPerInt; - nonstatic_word_space_count -= 1; - } else { - real_offset = next_nonstatic_word_offset; - next_nonstatic_word_offset += BytesPerInt; - } - break; - case NONSTATIC_DOUBLE: - real_offset = next_nonstatic_double_offset; - next_nonstatic_double_offset += BytesPerLong; - break; - default: - ShouldNotReachHere(); - } - fs.set_offset(real_offset); - } - - - // Handle the contended cases. - // - // Each contended field should not intersect the cache line with another contended field. - // In the absence of alignment information, we end up with pessimistically separating - // the fields with full-width padding. - // - // Additionally, this should not break alignment for the fields, so we round the alignment up - // for each field. - if (nonstatic_contended_count > 0) { - - // if there is at least one contended field, we need to have pre-padding for them - next_nonstatic_padded_offset += ContendedPaddingWidth; - - // collect all contended groups - BitMap bm(_cp->size()); - for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { - // skip already laid out fields - if (fs.is_offset_set()) continue; - - if (fs.is_contended()) { - bm.set_bit(fs.contended_group()); - } - } - - int current_group = -1; - while ((current_group = (int)bm.get_next_one_offset(current_group + 1)) != (int)bm.size()) { - - for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { - - // skip already laid out fields - if (fs.is_offset_set()) continue; - - // skip non-contended fields and fields from different group - if (!fs.is_contended() || (fs.contended_group() != current_group)) continue; - - // handle statics below - if (fs.access_flags().is_static()) continue; - - int real_offset; - FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); - - switch (atype) { - case NONSTATIC_BYTE: - next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, 1); - real_offset = next_nonstatic_padded_offset; - next_nonstatic_padded_offset += 1; - break; - - case NONSTATIC_SHORT: - next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerShort); - real_offset = next_nonstatic_padded_offset; - next_nonstatic_padded_offset += BytesPerShort; - break; - - case NONSTATIC_WORD: - next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerInt); - real_offset = next_nonstatic_padded_offset; - next_nonstatic_padded_offset += BytesPerInt; - break; - - case NONSTATIC_DOUBLE: - next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerLong); - real_offset = next_nonstatic_padded_offset; - next_nonstatic_padded_offset += BytesPerLong; - break; - - case NONSTATIC_OOP: - next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, heapOopSize); - real_offset = next_nonstatic_padded_offset; - next_nonstatic_padded_offset += heapOopSize; - - // Create new oop map - assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check"); - nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset; - nonstatic_oop_counts [nonstatic_oop_map_count] = 1; - nonstatic_oop_map_count += 1; - if( first_nonstatic_oop_offset == 0 ) { // Undefined - first_nonstatic_oop_offset = real_offset; - } - break; - - default: - ShouldNotReachHere(); - } - - if (fs.contended_group() == 0) { - // Contended group defines the equivalence class over the fields: - // the fields within the same contended group are not inter-padded. - // The only exception is default group, which does not incur the - // equivalence, and so requires intra-padding. - next_nonstatic_padded_offset += ContendedPaddingWidth; - } - - fs.set_offset(real_offset); - } // for - - // Start laying out the next group. - // Note that this will effectively pad the last group in the back; - // this is expected to alleviate memory contention effects for - // subclass fields and/or adjacent object. - // If this was the default group, the padding is already in place. - if (current_group != 0) { - next_nonstatic_padded_offset += ContendedPaddingWidth; - } - } - - // handle static fields - } - - // Entire class is contended, pad in the back. - // This helps to alleviate memory contention effects for subclass fields - // and/or adjacent object. - if (is_contended_class) { - next_nonstatic_padded_offset += ContendedPaddingWidth; - } - - int notaligned_nonstatic_fields_end = next_nonstatic_padded_offset; - - int nonstatic_fields_end = align_size_up(notaligned_nonstatic_fields_end, heapOopSize); - int instance_end = align_size_up(notaligned_nonstatic_fields_end, wordSize); - int static_fields_end = align_size_up(next_static_byte_offset, wordSize); - - int static_field_size = (static_fields_end - - InstanceMirrorKlass::offset_of_static_fields()) / wordSize; - nonstatic_field_size = nonstatic_field_size + - (nonstatic_fields_end - nonstatic_fields_start) / heapOopSize; - - int instance_size = align_object_size(instance_end / wordSize); - - assert(instance_size == align_object_size(align_size_up( - (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), - wordSize) / wordSize), "consistent layout helper value"); - - // Invariant: nonstatic_field end/start should only change if there are - // nonstatic fields in the class, or if the class is contended. We compare - // against the non-aligned value, so that end alignment will not fail the - // assert without actually having the fields. - assert((notaligned_nonstatic_fields_end == nonstatic_fields_start) || - is_contended_class || - (nonstatic_fields_count > 0), "double-check nonstatic start/end"); - - // Number of non-static oop map blocks allocated at end of klass. - const unsigned int total_oop_map_count = - compute_oop_map_count(_super_klass, nonstatic_oop_map_count, - first_nonstatic_oop_offset); - -#ifndef PRODUCT - if (PrintFieldLayout) { - print_field_layout(_class_name, - _fields, - _cp, - instance_size, - nonstatic_fields_start, - nonstatic_fields_end, - static_fields_end); - } - -#endif - // Pass back information needed for InstanceKlass creation - info->nonstatic_oop_offsets = nonstatic_oop_offsets; - info->nonstatic_oop_counts = nonstatic_oop_counts; - info->nonstatic_oop_map_count = nonstatic_oop_map_count; - info->total_oop_map_count = total_oop_map_count; - info->instance_size = instance_size; - info->static_field_size = static_field_size; - info->nonstatic_field_size = nonstatic_field_size; - info->has_nonstatic_fields = has_nonstatic_fields; -} - - -instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, - ClassLoaderData* loader_data, - Handle protection_domain, - KlassHandle host_klass, - GrowableArray* cp_patches, - TempNewSymbol& parsed_name, - bool verify, - TRAPS) { - - // When a retransformable agent is attached, JVMTI caches the - // class bytes that existed before the first retransformation. - // If RedefineClasses() was used before the retransformable - // agent attached, then the cached class bytes may not be the - // original class bytes. - JvmtiCachedClassFileData *cached_class_file = NULL; - Handle class_loader(THREAD, loader_data->class_loader()); - bool has_default_methods = false; - ResourceMark rm(THREAD); - - ClassFileStream* cfs = stream(); - // Timing - assert(THREAD->is_Java_thread(), "must be a JavaThread"); - JavaThread* jt = (JavaThread*) THREAD; - - PerfClassTraceTime ctimer(ClassLoader::perf_class_parse_time(), - ClassLoader::perf_class_parse_selftime(), - NULL, - jt->get_thread_stat()->perf_recursion_counts_addr(), - jt->get_thread_stat()->perf_timers_addr(), - PerfClassTraceTime::PARSE_CLASS); - - init_parsed_class_attributes(loader_data); - - if (JvmtiExport::should_post_class_file_load_hook()) { - // Get the cached class file bytes (if any) from the class that - // is being redefined or retransformed. We use jvmti_thread_state() - // instead of JvmtiThreadState::state_for(jt) so we don't allocate - // a JvmtiThreadState any earlier than necessary. This will help - // avoid the bug described by 7126851. - JvmtiThreadState *state = jt->jvmti_thread_state(); - if (state != NULL) { - KlassHandle *h_class_being_redefined = - state->get_class_being_redefined(); - if (h_class_being_redefined != NULL) { - instanceKlassHandle ikh_class_being_redefined = - instanceKlassHandle(THREAD, (*h_class_being_redefined)()); - cached_class_file = ikh_class_being_redefined->get_cached_class_file(); - } - } - - unsigned char* ptr = cfs->buffer(); - unsigned char* end_ptr = cfs->buffer() + cfs->length(); - - JvmtiExport::post_class_file_load_hook(name, class_loader(), protection_domain, - &ptr, &end_ptr, &cached_class_file); - - if (ptr != cfs->buffer()) { - // JVMTI agent has modified class file data. - // Set new class file stream using JVMTI agent modified - // class file data. - cfs = new ClassFileStream(ptr, end_ptr - ptr, cfs->source()); - set_stream(cfs); - } - } - - _host_klass = host_klass; - _cp_patches = cp_patches; - - instanceKlassHandle nullHandle; - - // Figure out whether we can skip format checking (matching classic VM behavior) - if (DumpSharedSpaces) { - // verify == true means it's a 'remote' class (i.e., non-boot class) - // Verification decision is based on BytecodeVerificationRemote flag - // for those classes. - _need_verify = (verify) ? BytecodeVerificationRemote : - BytecodeVerificationLocal; - } else { - _need_verify = Verifier::should_verify_for(class_loader(), verify); - } - - // Set the verify flag in stream - cfs->set_verify(_need_verify); - - // Save the class file name for easier error message printing. - _class_name = (name != NULL) ? name : vmSymbols::unknown_class_name(); - - cfs->guarantee_more(8, CHECK_(nullHandle)); // magic, major, minor - // Magic value - u4 magic = cfs->get_u4_fast(); - guarantee_property(magic == JAVA_CLASSFILE_MAGIC, - "Incompatible magic value %u in class file %s", - magic, CHECK_(nullHandle)); - - // Version numbers - u2 minor_version = cfs->get_u2_fast(); - u2 major_version = cfs->get_u2_fast(); - - if (DumpSharedSpaces && major_version < JAVA_1_5_VERSION) { - ResourceMark rm; - warning("Pre JDK 1.5 class not supported by CDS: %u.%u %s", - major_version, minor_version, name->as_C_string()); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_UnsupportedClassVersionError(), - "Unsupported major.minor version for dump time %u.%u", - major_version, - minor_version); - } - - // Check version numbers - we check this even with verifier off - if (!is_supported_version(major_version, minor_version)) { - if (name == NULL) { - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_UnsupportedClassVersionError(), - "Unsupported class file version %u.%u, " - "this version of the Java Runtime only recognizes class file versions up to %u.%u", - major_version, - minor_version, - JAVA_MAX_SUPPORTED_VERSION, - JAVA_MAX_SUPPORTED_MINOR_VERSION); - } else { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_UnsupportedClassVersionError(), - "%s has been compiled by a more recent version of the Java Runtime (class file version %u.%u), " - "this version of the Java Runtime only recognizes class file versions up to %u.%u", - name->as_C_string(), - major_version, - minor_version, - JAVA_MAX_SUPPORTED_VERSION, - JAVA_MAX_SUPPORTED_MINOR_VERSION); - } - return nullHandle; - } - - _major_version = major_version; - _minor_version = minor_version; - - - // Check if verification needs to be relaxed for this class file - // Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376) - _relax_verify = Verifier::relax_verify_for(class_loader()); - - // Constant pool - constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle)); - - int cp_size = cp->length(); - - cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len - - // Access flags - AccessFlags access_flags; - jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_CLASS_MODIFIERS; - - if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) { - // Set abstract bit for old class files for backward compatibility - flags |= JVM_ACC_ABSTRACT; - } - verify_legal_class_modifiers(flags, CHECK_(nullHandle)); - access_flags.set_flags(flags); - - // This class and superclass - u2 this_class_index = cfs->get_u2_fast(); - check_property( - valid_cp_range(this_class_index, cp_size) && - cp->tag_at(this_class_index).is_unresolved_klass(), - "Invalid this class index %u in constant pool in class file %s", - this_class_index, CHECK_(nullHandle)); - - Symbol* class_name = cp->klass_name_at(this_class_index); - assert(class_name != NULL, "class_name can't be null"); - - // It's important to set parsed_name *before* resolving the super class. - // (it's used for cleanup by the caller if parsing fails) - parsed_name = class_name; - // parsed_name is returned and can be used if there's an error, so add to - // its reference count. Caller will decrement the refcount. - parsed_name->increment_refcount(); - - // Update _class_name which could be null previously to be class_name - _class_name = class_name; - - // Don't need to check whether this class name is legal or not. - // It has been checked when constant pool is parsed. - // However, make sure it is not an array type. - if (_need_verify) { - guarantee_property(class_name->byte_at(0) != JVM_SIGNATURE_ARRAY, - "Bad class name in class file %s", - CHECK_(nullHandle)); - } - - Klass* preserve_this_klass; // for storing result across HandleMark - - // release all handles when parsing is done - { HandleMark hm(THREAD); - - // Checks if name in class file matches requested name - if (name != NULL && class_name != name) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_NoClassDefFoundError(), - "%s (wrong name: %s)", - name->as_C_string(), - class_name->as_C_string() - ); - return nullHandle; - } - - if (TraceClassLoadingPreorder) { - tty->print("[Loading %s", (name != NULL) ? name->as_klass_external_name() : "NoName"); - if (cfs->source() != NULL) tty->print(" from %s", cfs->source()); - tty->print_cr("]"); - } -#if INCLUDE_CDS - if (DumpLoadedClassList != NULL && cfs->source() != NULL && classlist_file->is_open()) { - // Only dump the classes that can be stored into CDS archive - if (SystemDictionaryShared::is_sharing_possible(loader_data)) { - if (name != NULL) { - ResourceMark rm(THREAD); - classlist_file->print_cr("%s", name->as_C_string()); - classlist_file->flush(); - } - } - } -#endif - - u2 super_class_index = cfs->get_u2_fast(); - instanceKlassHandle super_klass = parse_super_class(super_class_index, - CHECK_NULL); - - // Interfaces - u2 itfs_len = cfs->get_u2_fast(); - Array* local_interfaces = - parse_interfaces(itfs_len, protection_domain, _class_name, - &has_default_methods, CHECK_(nullHandle)); - - u2 java_fields_count = 0; - // Fields (offsets are filled in later) - FieldAllocationCount fac; - Array* fields = parse_fields(class_name, - access_flags.is_interface(), - &fac, &java_fields_count, - CHECK_(nullHandle)); - // Methods - bool has_final_method = false; - AccessFlags promoted_flags; - promoted_flags.set_flags(0); - Array* methods = parse_methods(access_flags.is_interface(), - &promoted_flags, - &has_final_method, - &has_default_methods, - CHECK_(nullHandle)); - - // Additional attributes - ClassAnnotationCollector parsed_annotations; - parse_classfile_attributes(&parsed_annotations, CHECK_(nullHandle)); - - // Make sure this is the end of class file stream - guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle)); - - // We check super class after class file is parsed and format is checked - if (super_class_index > 0 && super_klass.is_null()) { - Symbol* sk = cp->klass_name_at(super_class_index); - if (access_flags.is_interface()) { - // Before attempting to resolve the superclass, check for class format - // errors not checked yet. - guarantee_property(sk == vmSymbols::java_lang_Object(), - "Interfaces must have java.lang.Object as superclass in class file %s", - CHECK_(nullHandle)); - } - Klass* k = SystemDictionary::resolve_super_or_fail(class_name, sk, - class_loader, - protection_domain, - true, - CHECK_(nullHandle)); - - KlassHandle kh (THREAD, k); - super_klass = instanceKlassHandle(THREAD, kh()); - } - if (super_klass.not_null()) { - - if (super_klass->has_default_methods()) { - has_default_methods = true; - } - - if (super_klass->is_interface()) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_IncompatibleClassChangeError(), - "class %s has interface %s as super class", - class_name->as_klass_external_name(), - super_klass->external_name() - ); - return nullHandle; - } - // Make sure super class is not final - if (super_klass->is_final()) { - THROW_MSG_(vmSymbols::java_lang_VerifyError(), "Cannot inherit from final class", nullHandle); - } - } - - // save super klass for error handling. - _super_klass = super_klass; - - // Compute the transitive list of all unique interfaces implemented by this class - _transitive_interfaces = - compute_transitive_interfaces(super_klass, local_interfaces, CHECK_(nullHandle)); - - // sort methods - intArray* method_ordering = sort_methods(methods); - - // promote flags from parse_methods() to the klass' flags - access_flags.add_promoted_flags(promoted_flags.as_int()); - - // Size of Java vtable (in words) - int vtable_size = 0; - int itable_size = 0; - int num_miranda_methods = 0; - - GrowableArray all_mirandas(20); - - klassVtable::compute_vtable_size_and_num_mirandas( - &vtable_size, &num_miranda_methods, &all_mirandas, super_klass(), methods, - access_flags, class_loader, class_name, local_interfaces, - CHECK_(nullHandle)); - - // Size of Java itable (in words) - itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(_transitive_interfaces); - - FieldLayoutInfo info; - layout_fields(class_loader, &fac, &parsed_annotations, &info, CHECK_NULL); - - int total_oop_map_size2 = - InstanceKlass::nonstatic_oop_map_size(info.total_oop_map_count); - - // Compute reference type - ReferenceType rt; - if (super_klass() == NULL) { - rt = REF_NONE; - } else { - rt = super_klass->reference_type(); - } - - // We can now create the basic Klass* for this klass - _klass = InstanceKlass::allocate_instance_klass(loader_data, - vtable_size, - itable_size, - info.static_field_size, - total_oop_map_size2, - rt, - access_flags, - name, - super_klass(), - !host_klass.is_null(), - CHECK_(nullHandle)); - instanceKlassHandle this_klass (THREAD, _klass); - - assert(this_klass->static_field_size() == info.static_field_size, "sanity"); - assert(this_klass->nonstatic_oop_map_count() == info.total_oop_map_count, - "sanity"); - - // Fill in information already parsed - this_klass->set_should_verify_class(verify); - jint lh = Klass::instance_layout_helper(info.instance_size, false); - this_klass->set_layout_helper(lh); - assert(this_klass->oop_is_instance(), "layout is correct"); - assert(this_klass->size_helper() == info.instance_size, "correct size_helper"); - // Not yet: supers are done below to support the new subtype-checking fields - //this_klass->set_super(super_klass()); - this_klass->set_class_loader_data(loader_data); - this_klass->set_nonstatic_field_size(info.nonstatic_field_size); - this_klass->set_has_nonstatic_fields(info.has_nonstatic_fields); - this_klass->set_static_oop_field_count(fac.count[STATIC_OOP]); - - apply_parsed_class_metadata(this_klass, java_fields_count, CHECK_NULL); - - if (has_final_method) { - this_klass->set_has_final_method(); - } - this_klass->copy_method_ordering(method_ordering, CHECK_NULL); - // The InstanceKlass::_methods_jmethod_ids cache - // is managed on the assumption that the initial cache - // size is equal to the number of methods in the class. If - // that changes, then InstanceKlass::idnum_can_increment() - // has to be changed accordingly. - this_klass->set_initial_method_idnum(methods->length()); - this_klass->set_name(cp->klass_name_at(this_class_index)); - if (is_anonymous()) // I am well known to myself - cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve - - this_klass->set_minor_version(minor_version); - this_klass->set_major_version(major_version); - this_klass->set_has_default_methods(has_default_methods); - - if (!host_klass.is_null()) { - assert (this_klass->is_anonymous(), "should be the same"); - this_klass->set_host_klass(host_klass()); - } - - // Set up Method*::intrinsic_id as soon as we know the names of methods. - // (We used to do this lazily, but now we query it in Rewriter, - // which is eagerly done for every method, so we might as well do it now, - // when everything is fresh in memory.) - if (Method::klass_id_for_intrinsics(this_klass()) != vmSymbols::NO_SID) { - for (int j = 0; j < methods->length(); j++) { - methods->at(j)->init_intrinsic_id(); - } - } - - if (cached_class_file != NULL) { - // JVMTI: we have an InstanceKlass now, tell it about the cached bytes - this_klass->set_cached_class_file(cached_class_file); - } - - // Fill in field values obtained by parse_classfile_attributes - if (parsed_annotations.has_any_annotations()) - parsed_annotations.apply_to(this_klass); - apply_parsed_class_attributes(this_klass); - - // Miranda methods - if ((num_miranda_methods > 0) || - // if this class introduced new miranda methods or - (super_klass.not_null() && (super_klass->has_miranda_methods())) - // super class exists and this class inherited miranda methods - ) { - this_klass->set_has_miranda_methods(); // then set a flag - } - - // Fill in information needed to compute superclasses. - this_klass->initialize_supers(super_klass(), CHECK_(nullHandle)); - - // Initialize itable offset tables - klassItable::setup_itable_offset_table(this_klass); - - // Compute transitive closure of interfaces this class implements - // Do final class setup - fill_oop_maps(this_klass, info.nonstatic_oop_map_count, info.nonstatic_oop_offsets, info.nonstatic_oop_counts); - - // Fill in has_finalizer, has_vanilla_constructor, and layout_helper - set_precomputed_flags(this_klass); - - // reinitialize modifiers, using the InnerClasses attribute - int computed_modifiers = this_klass->compute_modifier_flags(CHECK_(nullHandle)); - this_klass->set_modifier_flags(computed_modifiers); - - // check if this class can access its super class - check_super_class_access(this_klass, CHECK_(nullHandle)); - - // check if this class can access its superinterfaces - check_super_interface_access(this_klass, CHECK_(nullHandle)); - - // check if this class overrides any final method - check_final_method_override(this_klass, CHECK_(nullHandle)); - - // check that if this class is an interface then it doesn't have static methods - if (this_klass->is_interface()) { - /* An interface in a JAVA 8 classfile can be static */ - if (_major_version < JAVA_8_VERSION) { - check_illegal_static_method(this_klass, CHECK_(nullHandle)); - } - } - - // Allocate mirror and initialize static fields - java_lang_Class::create_mirror(this_klass, class_loader, protection_domain, - CHECK_(nullHandle)); - - // Generate any default methods - default methods are interface methods - // that have a default implementation. This is new with Lambda project. - if (has_default_methods ) { - DefaultMethods::generate_default_methods( - this_klass(), &all_mirandas, CHECK_(nullHandle)); - } - - // Update the loader_data graph. - record_defined_class_dependencies(this_klass, CHECK_NULL); - - ClassLoadingService::notify_class_loaded(InstanceKlass::cast(this_klass()), - false /* not shared class */); - - if (TraceClassLoading) { - ResourceMark rm; - // print in a single call to reduce interleaving of output - if (cfs->source() != NULL) { - tty->print("[Loaded %s from %s]\n", this_klass->external_name(), - cfs->source()); - } else if (class_loader.is_null()) { - Klass* caller = - THREAD->is_Java_thread() - ? ((JavaThread*)THREAD)->security_get_caller_class(1) - : NULL; - // caller can be NULL, for example, during a JVMTI VM_Init hook - if (caller != NULL) { - tty->print("[Loaded %s by instance of %s]\n", - this_klass->external_name(), - InstanceKlass::cast(caller)->external_name()); - } else { - tty->print("[Loaded %s]\n", this_klass->external_name()); - } - } else { - tty->print("[Loaded %s from %s]\n", this_klass->external_name(), - InstanceKlass::cast(class_loader->klass())->external_name()); - } - } - - if (TraceClassResolution) { - ResourceMark rm; - // print out the superclass. - const char * from = this_klass()->external_name(); - if (this_klass->java_super() != NULL) { - tty->print("RESOLVE %s %s (super)\n", from, InstanceKlass::cast(this_klass->java_super())->external_name()); - } - // print out each of the interface classes referred to by this class. - Array* local_interfaces = this_klass->local_interfaces(); - if (local_interfaces != NULL) { - int length = local_interfaces->length(); - for (int i = 0; i < length; i++) { - Klass* k = local_interfaces->at(i); - InstanceKlass* to_class = InstanceKlass::cast(k); - const char * to = to_class->external_name(); - tty->print("RESOLVE %s %s (interface)\n", from, to); - } - } - } - - // preserve result across HandleMark - preserve_this_klass = this_klass(); - } - - // Create new handle outside HandleMark (might be needed for - // Extended Class Redefinition) - instanceKlassHandle this_klass (THREAD, preserve_this_klass); - debug_only(this_klass->verify();) - - // Clear class if no error has occurred so destructor doesn't deallocate it - _klass = NULL; - return this_klass; -} - -// Destructor to clean up if there's an error -ClassFileParser::~ClassFileParser() { - MetadataFactory::free_metadata(_loader_data, _cp); - MetadataFactory::free_array(_loader_data, _fields); - - // Free methods - InstanceKlass::deallocate_methods(_loader_data, _methods); - - // beware of the Universe::empty_blah_array!! - if (_inner_classes != Universe::the_empty_short_array()) { - MetadataFactory::free_array(_loader_data, _inner_classes); - } - - // Free interfaces - InstanceKlass::deallocate_interfaces(_loader_data, _super_klass(), - _local_interfaces, _transitive_interfaces); - - MetadataFactory::free_array(_loader_data, _annotations); - MetadataFactory::free_array(_loader_data, _type_annotations); - Annotations::free_contents(_loader_data, _fields_annotations); - Annotations::free_contents(_loader_data, _fields_type_annotations); - - clear_class_metadata(); - - // deallocate the klass if already created. Don't directly deallocate, but add - // to the deallocate list so that the klass is removed from the CLD::_klasses list - // at a safepoint. - if (_klass != NULL) { - _loader_data->add_to_deallocate_list(_klass); - } - _klass = NULL; -} - -void ClassFileParser::print_field_layout(Symbol* name, - Array* fields, - constantPoolHandle cp, - int instance_size, - int instance_fields_start, - int instance_fields_end, - int static_fields_end) { - tty->print("%s: field layout\n", name->as_klass_external_name()); - tty->print(" @%3d %s\n", instance_fields_start, "--- instance fields start ---"); - for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { - if (!fs.access_flags().is_static()) { - tty->print(" @%3d \"%s\" %s\n", - fs.offset(), - fs.name()->as_klass_external_name(), - fs.signature()->as_klass_external_name()); - } - } - tty->print(" @%3d %s\n", instance_fields_end, "--- instance fields end ---"); - tty->print(" @%3d %s\n", instance_size * wordSize, "--- instance ends ---"); - tty->print(" @%3d %s\n", InstanceMirrorKlass::offset_of_static_fields(), "--- static fields start ---"); - for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { - if (fs.access_flags().is_static()) { - tty->print(" @%3d \"%s\" %s\n", - fs.offset(), - fs.name()->as_klass_external_name(), - fs.signature()->as_klass_external_name()); - } - } - tty->print(" @%3d %s\n", static_fields_end, "--- static fields end ---"); - tty->print("\n"); -} - -unsigned int -ClassFileParser::compute_oop_map_count(instanceKlassHandle super, - unsigned int nonstatic_oop_map_count, - int first_nonstatic_oop_offset) { - unsigned int map_count = - super.is_null() ? 0 : super->nonstatic_oop_map_count(); - if (nonstatic_oop_map_count > 0) { - // We have oops to add to map - if (map_count == 0) { - map_count = nonstatic_oop_map_count; - } else { - // Check whether we should add a new map block or whether the last one can - // be extended - OopMapBlock* const first_map = super->start_of_nonstatic_oop_maps(); - OopMapBlock* const last_map = first_map + map_count - 1; - - int next_offset = last_map->offset() + last_map->count() * heapOopSize; - if (next_offset == first_nonstatic_oop_offset) { - // There is no gap bettwen superklass's last oop field and first - // local oop field, merge maps. - nonstatic_oop_map_count -= 1; - } else { - // Superklass didn't end with a oop field, add extra maps - assert(next_offset < first_nonstatic_oop_offset, "just checking"); - } - map_count += nonstatic_oop_map_count; - } - } - return map_count; -} - - -void ClassFileParser::fill_oop_maps(instanceKlassHandle k, - unsigned int nonstatic_oop_map_count, - int* nonstatic_oop_offsets, - unsigned int* nonstatic_oop_counts) { - OopMapBlock* this_oop_map = k->start_of_nonstatic_oop_maps(); - const InstanceKlass* const super = k->superklass(); - const unsigned int super_count = super ? super->nonstatic_oop_map_count() : 0; - if (super_count > 0) { - // Copy maps from superklass - OopMapBlock* super_oop_map = super->start_of_nonstatic_oop_maps(); - for (unsigned int i = 0; i < super_count; ++i) { - *this_oop_map++ = *super_oop_map++; - } - } - - if (nonstatic_oop_map_count > 0) { - if (super_count + nonstatic_oop_map_count > k->nonstatic_oop_map_count()) { - // The counts differ because there is no gap between superklass's last oop - // field and the first local oop field. Extend the last oop map copied - // from the superklass instead of creating new one. - nonstatic_oop_map_count--; - nonstatic_oop_offsets++; - this_oop_map--; - this_oop_map->set_count(this_oop_map->count() + *nonstatic_oop_counts++); - this_oop_map++; - } - - // Add new map blocks, fill them - while (nonstatic_oop_map_count-- > 0) { - this_oop_map->set_offset(*nonstatic_oop_offsets++); - this_oop_map->set_count(*nonstatic_oop_counts++); - this_oop_map++; - } - assert(k->start_of_nonstatic_oop_maps() + k->nonstatic_oop_map_count() == - this_oop_map, "sanity"); - } -} - - -void ClassFileParser::set_precomputed_flags(instanceKlassHandle k) { - Klass* super = k->super(); - - // Check if this klass has an empty finalize method (i.e. one with return bytecode only), - // in which case we don't have to register objects as finalizable - if (!_has_empty_finalizer) { - if (_has_finalizer || - (super != NULL && super->has_finalizer())) { - k->set_has_finalizer(); - } - } - -#ifdef ASSERT - bool f = false; - Method* m = k->lookup_method(vmSymbols::finalize_method_name(), - vmSymbols::void_method_signature()); - if (m != NULL && !m->is_empty_method()) { - f = true; - } - - // Spec doesn't prevent agent from redefinition of empty finalizer. - // Despite the fact that it's generally bad idea and redefined finalizer - // will not work as expected we shouldn't abort vm in this case - if (!k->has_redefined_this_or_super()) { - assert(f == k->has_finalizer(), "inconsistent has_finalizer"); - } -#endif - - // Check if this klass supports the java.lang.Cloneable interface - if (SystemDictionary::Cloneable_klass_loaded()) { - if (k->is_subtype_of(SystemDictionary::Cloneable_klass())) { - k->set_is_cloneable(); - } - } - - // Check if this klass has a vanilla default constructor - if (super == NULL) { - // java.lang.Object has empty default constructor - k->set_has_vanilla_constructor(); - } else { - if (super->has_vanilla_constructor() && - _has_vanilla_constructor) { - k->set_has_vanilla_constructor(); - } -#ifdef ASSERT - bool v = false; - if (super->has_vanilla_constructor()) { - Method* constructor = k->find_method(vmSymbols::object_initializer_name( -), vmSymbols::void_method_signature()); - if (constructor != NULL && constructor->is_vanilla_constructor()) { - v = true; - } - } - assert(v == k->has_vanilla_constructor(), "inconsistent has_vanilla_constructor"); -#endif - } - - // If it cannot be fast-path allocated, set a bit in the layout helper. - // See documentation of InstanceKlass::can_be_fastpath_allocated(). - assert(k->size_helper() > 0, "layout_helper is initialized"); - if ((!RegisterFinalizersAtInit && k->has_finalizer()) - || k->is_abstract() || k->is_interface() - || (k->name() == vmSymbols::java_lang_Class() && k->class_loader() == NULL) - || k->size_helper() >= FastAllocateSizeLimit) { - // Forbid fast-path allocation. - jint lh = Klass::instance_layout_helper(k->size_helper(), true); - k->set_layout_helper(lh); - } -} - -// Attach super classes and interface classes to class loader data -void ClassFileParser::record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS) { - ClassLoaderData * defining_loader_data = defined_klass->class_loader_data(); - if (defining_loader_data->is_the_null_class_loader_data()) { - // Dependencies to null class loader data are implicit. - return; - } else { - // add super class dependency - Klass* super = defined_klass->super(); - if (super != NULL) { - defining_loader_data->record_dependency(super, CHECK); - } - - // add super interface dependencies - Array* local_interfaces = defined_klass->local_interfaces(); - if (local_interfaces != NULL) { - int length = local_interfaces->length(); - for (int i = 0; i < length; i++) { - defining_loader_data->record_dependency(local_interfaces->at(i), CHECK); - } - } - } -} - -// utility methods for appending an array with check for duplicates - -void append_interfaces(GrowableArray* result, Array* ifs) { - // iterate over new interfaces - for (int i = 0; i < ifs->length(); i++) { - Klass* e = ifs->at(i); - assert(e->is_klass() && InstanceKlass::cast(e)->is_interface(), "just checking"); - // add new interface - result->append_if_missing(e); - } -} - -Array* ClassFileParser::compute_transitive_interfaces( - instanceKlassHandle super, - Array* local_ifs, TRAPS) { - // Compute maximum size for transitive interfaces - int max_transitive_size = 0; - int super_size = 0; - // Add superclass transitive interfaces size - if (super.not_null()) { - super_size = super->transitive_interfaces()->length(); - max_transitive_size += super_size; - } - // Add local interfaces' super interfaces - int local_size = local_ifs->length(); - for (int i = 0; i < local_size; i++) { - Klass* l = local_ifs->at(i); - max_transitive_size += InstanceKlass::cast(l)->transitive_interfaces()->length(); - } - // Finally add local interfaces - max_transitive_size += local_size; - // Construct array - if (max_transitive_size == 0) { - // no interfaces, use canonicalized array - return Universe::the_empty_klass_array(); - } else if (max_transitive_size == super_size) { - // no new local interfaces added, share superklass' transitive interface array - return super->transitive_interfaces(); - } else if (max_transitive_size == local_size) { - // only local interfaces added, share local interface array - return local_ifs; - } else { - ResourceMark rm; - GrowableArray* result = new GrowableArray(max_transitive_size); - - // Copy down from superclass - if (super.not_null()) { - append_interfaces(result, super->transitive_interfaces()); - } - - // Copy down from local interfaces' superinterfaces - for (int i = 0; i < local_ifs->length(); i++) { - Klass* l = local_ifs->at(i); - append_interfaces(result, InstanceKlass::cast(l)->transitive_interfaces()); - } - // Finally add local interfaces - append_interfaces(result, local_ifs); - - // length will be less than the max_transitive_size if duplicates were removed - int length = result->length(); - assert(length <= max_transitive_size, "just checking"); - Array* new_result = MetadataFactory::new_array(_loader_data, length, CHECK_NULL); - for (int i = 0; i < length; i++) { - Klass* e = result->at(i); - assert(e != NULL, "just checking"); - new_result->at_put(i, e); - } - return new_result; - } -} - -void ClassFileParser::check_super_class_access(instanceKlassHandle this_klass, TRAPS) { - Klass* super = this_klass->super(); - if ((super != NULL) && - (!Reflection::verify_class_access(this_klass(), super, false))) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_IllegalAccessError(), - "class %s cannot access its superclass %s", - this_klass->external_name(), - InstanceKlass::cast(super)->external_name() - ); - return; - } -} - - -void ClassFileParser::check_super_interface_access(instanceKlassHandle this_klass, TRAPS) { - Array* local_interfaces = this_klass->local_interfaces(); - int lng = local_interfaces->length(); - for (int i = lng - 1; i >= 0; i--) { - Klass* k = local_interfaces->at(i); - assert (k != NULL && k->is_interface(), "invalid interface"); - if (!Reflection::verify_class_access(this_klass(), k, false)) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_IllegalAccessError(), - "class %s cannot access its superinterface %s", - this_klass->external_name(), - InstanceKlass::cast(k)->external_name() - ); - return; - } - } -} - - -void ClassFileParser::check_final_method_override(instanceKlassHandle this_klass, TRAPS) { - Array* methods = this_klass->methods(); - int num_methods = methods->length(); - - // go thru each method and check if it overrides a final method - for (int index = 0; index < num_methods; index++) { - Method* m = methods->at(index); - - // skip private, static, and methods - if ((!m->is_private() && !m->is_static()) && - (m->name() != vmSymbols::object_initializer_name())) { - - Symbol* name = m->name(); - Symbol* signature = m->signature(); - Klass* k = this_klass->super(); - Method* super_m = NULL; - while (k != NULL) { - // skip supers that don't have final methods. - if (k->has_final_method()) { - // lookup a matching method in the super class hierarchy - super_m = InstanceKlass::cast(k)->lookup_method(name, signature); - if (super_m == NULL) { - break; // didn't find any match; get out - } - - if (super_m->is_final() && !super_m->is_static() && - // matching method in super is final, and not static - (Reflection::verify_field_access(this_klass(), - super_m->method_holder(), - super_m->method_holder(), - super_m->access_flags(), false)) - // this class can access super final method and therefore override - ) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_VerifyError(), - "class %s overrides final method %s.%s%s", - this_klass->external_name(), - super_m->method_holder()->external_name(), - name->as_C_string(), - signature->as_C_string() - ); - return; - } - - // continue to look from super_m's holder's super. - k = super_m->method_holder()->super(); - continue; - } - - k = k->super(); - } - } - } -} - - -// assumes that this_klass is an interface -void ClassFileParser::check_illegal_static_method(instanceKlassHandle this_klass, TRAPS) { - assert(this_klass->is_interface(), "not an interface"); - Array* methods = this_klass->methods(); - int num_methods = methods->length(); - - for (int index = 0; index < num_methods; index++) { - Method* m = methods->at(index); - // if m is static and not the init method, throw a verify error - if ((m->is_static()) && (m->name() != vmSymbols::class_initializer_name())) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_VerifyError(), - "Illegal static method %s in interface %s", - m->name()->as_C_string(), - this_klass->external_name() - ); - return; - } - } -} - -// utility methods for format checking - -void ClassFileParser::verify_legal_class_modifiers(jint flags, TRAPS) { - if (!_need_verify) { return; } - - const bool is_interface = (flags & JVM_ACC_INTERFACE) != 0; - const bool is_abstract = (flags & JVM_ACC_ABSTRACT) != 0; - const bool is_final = (flags & JVM_ACC_FINAL) != 0; - const bool is_super = (flags & JVM_ACC_SUPER) != 0; - const bool is_enum = (flags & JVM_ACC_ENUM) != 0; - const bool is_annotation = (flags & JVM_ACC_ANNOTATION) != 0; - const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION; - - if ((is_abstract && is_final) || - (is_interface && !is_abstract) || - (is_interface && major_gte_15 && (is_super || is_enum)) || - (!is_interface && major_gte_15 && is_annotation)) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_ClassFormatError(), - "Illegal class modifiers in class %s: 0x%X", - _class_name->as_C_string(), flags - ); - return; - } -} - -bool ClassFileParser::has_illegal_visibility(jint flags) { - const bool is_public = (flags & JVM_ACC_PUBLIC) != 0; - const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0; - const bool is_private = (flags & JVM_ACC_PRIVATE) != 0; - - return ((is_public && is_protected) || - (is_public && is_private) || - (is_protected && is_private)); -} - -bool ClassFileParser::is_supported_version(u2 major, u2 minor) { - u2 max_version = JAVA_MAX_SUPPORTED_VERSION; - return (major >= JAVA_MIN_SUPPORTED_VERSION) && - (major <= max_version) && - ((major != max_version) || - (minor <= JAVA_MAX_SUPPORTED_MINOR_VERSION)); -} - -void ClassFileParser::verify_legal_field_modifiers( - jint flags, bool is_interface, TRAPS) { - if (!_need_verify) { return; } - - const bool is_public = (flags & JVM_ACC_PUBLIC) != 0; - const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0; - const bool is_private = (flags & JVM_ACC_PRIVATE) != 0; - const bool is_static = (flags & JVM_ACC_STATIC) != 0; - const bool is_final = (flags & JVM_ACC_FINAL) != 0; - const bool is_volatile = (flags & JVM_ACC_VOLATILE) != 0; - const bool is_transient = (flags & JVM_ACC_TRANSIENT) != 0; - const bool is_enum = (flags & JVM_ACC_ENUM) != 0; - const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION; - - bool is_illegal = false; - - if (is_interface) { - if (!is_public || !is_static || !is_final || is_private || - is_protected || is_volatile || is_transient || - (major_gte_15 && is_enum)) { - is_illegal = true; - } - } else { // not interface - if (has_illegal_visibility(flags) || (is_final && is_volatile)) { - is_illegal = true; - } - } - - if (is_illegal) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_ClassFormatError(), - "Illegal field modifiers in class %s: 0x%X", - _class_name->as_C_string(), flags); - return; - } -} - -void ClassFileParser::verify_legal_method_modifiers( - jint flags, bool is_interface, Symbol* name, TRAPS) { - if (!_need_verify) { return; } - - const bool is_public = (flags & JVM_ACC_PUBLIC) != 0; - const bool is_private = (flags & JVM_ACC_PRIVATE) != 0; - const bool is_static = (flags & JVM_ACC_STATIC) != 0; - const bool is_final = (flags & JVM_ACC_FINAL) != 0; - const bool is_native = (flags & JVM_ACC_NATIVE) != 0; - const bool is_abstract = (flags & JVM_ACC_ABSTRACT) != 0; - const bool is_bridge = (flags & JVM_ACC_BRIDGE) != 0; - const bool is_strict = (flags & JVM_ACC_STRICT) != 0; - const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 0; - const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0; - const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION; - const bool major_gte_8 = _major_version >= JAVA_8_VERSION; - const bool is_initializer = (name == vmSymbols::object_initializer_name()); - - bool is_illegal = false; - - if (is_interface) { - if (major_gte_8) { - // Class file version is JAVA_8_VERSION or later Methods of - // interfaces may set any of the flags except ACC_PROTECTED, - // ACC_FINAL, ACC_NATIVE, and ACC_SYNCHRONIZED; they must - // have exactly one of the ACC_PUBLIC or ACC_PRIVATE flags set. - if ((is_public == is_private) || /* Only one of private and public should be true - XNOR */ - (is_native || is_protected || is_final || is_synchronized) || - // If a specific method of a class or interface has its - // ACC_ABSTRACT flag set, it must not have any of its - // ACC_FINAL, ACC_NATIVE, ACC_PRIVATE, ACC_STATIC, - // ACC_STRICT, or ACC_SYNCHRONIZED flags set. No need to - // check for ACC_FINAL, ACC_NATIVE or ACC_SYNCHRONIZED as - // those flags are illegal irrespective of ACC_ABSTRACT being set or not. - (is_abstract && (is_private || is_static || is_strict))) { - is_illegal = true; - } - } else if (major_gte_15) { - // Class file version in the interval [JAVA_1_5_VERSION, JAVA_8_VERSION) - if (!is_public || is_static || is_final || is_synchronized || - is_native || !is_abstract || is_strict) { - is_illegal = true; - } - } else { - // Class file version is pre-JAVA_1_5_VERSION - if (!is_public || is_static || is_final || is_native || !is_abstract) { - is_illegal = true; - } - } - } else { // not interface - if (is_initializer) { - if (is_static || is_final || is_synchronized || is_native || - is_abstract || (major_gte_15 && is_bridge)) { - is_illegal = true; - } - } else { // not initializer - if (is_abstract) { - if ((is_final || is_native || is_private || is_static || - (major_gte_15 && (is_synchronized || is_strict)))) { - is_illegal = true; - } - } - if (has_illegal_visibility(flags)) { - is_illegal = true; - } - } - } - - if (is_illegal) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_ClassFormatError(), - "Method %s in class %s has illegal modifiers: 0x%X", - name->as_C_string(), _class_name->as_C_string(), flags); - return; - } -} - -void ClassFileParser::verify_legal_utf8(const unsigned char* buffer, int length, TRAPS) { - assert(_need_verify, "only called when _need_verify is true"); - int i = 0; - int count = length >> 2; - for (int k=0; k= 128 (highest bit 1) for v == 0 or v >= 128. - unsigned char res = b0 | b0 - 1 | - b1 | b1 - 1 | - b2 | b2 - 1 | - b3 | b3 - 1; - if (res >= 128) break; - i += 4; - } - for(; i < length; i++) { - unsigned short c; - // no embedded zeros - guarantee_property((buffer[i] != 0), "Illegal UTF8 string in constant pool in class file %s", CHECK); - if(buffer[i] < 128) { - continue; - } - if ((i + 5) < length) { // see if it's legal supplementary character - if (UTF8::is_supplementary_character(&buffer[i])) { - c = UTF8::get_supplementary_character(&buffer[i]); - i += 5; - continue; - } - } - switch (buffer[i] >> 4) { - default: break; - case 0x8: case 0x9: case 0xA: case 0xB: case 0xF: - classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK); - case 0xC: case 0xD: // 110xxxxx 10xxxxxx - c = (buffer[i] & 0x1F) << 6; - i++; - if ((i < length) && ((buffer[i] & 0xC0) == 0x80)) { - c += buffer[i] & 0x3F; - if (_major_version <= 47 || c == 0 || c >= 0x80) { - // for classes with major > 47, c must a null or a character in its shortest form - break; - } - } - classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK); - case 0xE: // 1110xxxx 10xxxxxx 10xxxxxx - c = (buffer[i] & 0xF) << 12; - i += 2; - if ((i < length) && ((buffer[i-1] & 0xC0) == 0x80) && ((buffer[i] & 0xC0) == 0x80)) { - c += ((buffer[i-1] & 0x3F) << 6) + (buffer[i] & 0x3F); - if (_major_version <= 47 || c >= 0x800) { - // for classes with major > 47, c must be in its shortest form - break; - } - } - classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK); - } // end of switch - } // end of for -} - -// Checks if name is a legal class name. -void ClassFileParser::verify_legal_class_name(Symbol* name, TRAPS) { - if (!_need_verify || _relax_verify) { return; } - - char buf[fixed_buffer_size]; - char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); - unsigned int length = name->utf8_length(); - bool legal = false; - - if (length > 0) { - char* p; - if (bytes[0] == JVM_SIGNATURE_ARRAY) { - p = skip_over_field_signature(bytes, false, length, CHECK); - legal = (p != NULL) && ((p - bytes) == (int)length); - } else if (_major_version < JAVA_1_5_VERSION) { - if (bytes[0] != '<') { - p = skip_over_field_name(bytes, true, length); - legal = (p != NULL) && ((p - bytes) == (int)length); - } - } else { - // 4900761: relax the constraints based on JSR202 spec - // Class names may be drawn from the entire Unicode character set. - // Identifiers between '/' must be unqualified names. - // The utf8 string has been verified when parsing cpool entries. - legal = verify_unqualified_name(bytes, length, LegalClass); - } - } - if (!legal) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_ClassFormatError(), - "Illegal class name \"%s\" in class file %s", bytes, - _class_name->as_C_string() - ); - return; - } -} - -// Checks if name is a legal field name. -void ClassFileParser::verify_legal_field_name(Symbol* name, TRAPS) { - if (!_need_verify || _relax_verify) { return; } - - char buf[fixed_buffer_size]; - char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); - unsigned int length = name->utf8_length(); - bool legal = false; - - if (length > 0) { - if (_major_version < JAVA_1_5_VERSION) { - if (bytes[0] != '<') { - char* p = skip_over_field_name(bytes, false, length); - legal = (p != NULL) && ((p - bytes) == (int)length); - } - } else { - // 4881221: relax the constraints based on JSR202 spec - legal = verify_unqualified_name(bytes, length, LegalField); - } - } - - if (!legal) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_ClassFormatError(), - "Illegal field name \"%s\" in class %s", bytes, - _class_name->as_C_string() - ); - return; - } -} - -// Checks if name is a legal method name. -void ClassFileParser::verify_legal_method_name(Symbol* name, TRAPS) { - if (!_need_verify || _relax_verify) { return; } - - assert(name != NULL, "method name is null"); - char buf[fixed_buffer_size]; - char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); - unsigned int length = name->utf8_length(); - bool legal = false; - - if (length > 0) { - if (bytes[0] == '<') { - if (name == vmSymbols::object_initializer_name() || name == vmSymbols::class_initializer_name()) { - legal = true; - } - } else if (_major_version < JAVA_1_5_VERSION) { - char* p; - p = skip_over_field_name(bytes, false, length); - legal = (p != NULL) && ((p - bytes) == (int)length); - } else { - // 4881221: relax the constraints based on JSR202 spec - legal = verify_unqualified_name(bytes, length, LegalMethod); - } - } - - if (!legal) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_ClassFormatError(), - "Illegal method name \"%s\" in class %s", bytes, - _class_name->as_C_string() - ); - return; - } -} - - -// Checks if signature is a legal field signature. -void ClassFileParser::verify_legal_field_signature(Symbol* name, Symbol* signature, TRAPS) { - if (!_need_verify) { return; } - - char buf[fixed_buffer_size]; - char* bytes = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); - unsigned int length = signature->utf8_length(); - char* p = skip_over_field_signature(bytes, false, length, CHECK); - - if (p == NULL || (p - bytes) != (int)length) { - throwIllegalSignature("Field", name, signature, CHECK); - } -} - -// Checks if signature is a legal method signature. -// Returns number of parameters -int ClassFileParser::verify_legal_method_signature(Symbol* name, Symbol* signature, TRAPS) { - if (!_need_verify) { - // make sure caller's args_size will be less than 0 even for non-static - // method so it will be recomputed in compute_size_of_parameters(). - return -2; - } - - unsigned int args_size = 0; - char buf[fixed_buffer_size]; - char* p = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size); - unsigned int length = signature->utf8_length(); - char* nextp; - - // The first character must be a '(' - if ((length > 0) && (*p++ == JVM_SIGNATURE_FUNC)) { - length--; - // Skip over legal field signatures - nextp = skip_over_field_signature(p, false, length, CHECK_0); - while ((length > 0) && (nextp != NULL)) { - args_size++; - if (p[0] == 'J' || p[0] == 'D') { - args_size++; - } - length -= nextp - p; - p = nextp; - nextp = skip_over_field_signature(p, false, length, CHECK_0); - } - // The first non-signature thing better be a ')' - if ((length > 0) && (*p++ == JVM_SIGNATURE_ENDFUNC)) { - length--; - if (name->utf8_length() > 0 && name->byte_at(0) == '<') { - // All internal methods must return void - if ((length == 1) && (p[0] == JVM_SIGNATURE_VOID)) { - return args_size; - } - } else { - // Now we better just have a return value - nextp = skip_over_field_signature(p, true, length, CHECK_0); - if (nextp && ((int)length == (nextp - p))) { - return args_size; - } - } - } - } - // Report error - throwIllegalSignature("Method", name, signature, CHECK_0); - return 0; -} - - -// Unqualified names may not contain the characters '.', ';', '[', or '/'. -// Method names also may not contain the characters '<' or '>', unless -// or . Note that method names may not be or in this -// method. Because these names have been checked as special cases before -// calling this method in verify_legal_method_name. -bool ClassFileParser::verify_unqualified_name( - char* name, unsigned int length, int type) { - jchar ch; - - for (char* p = name; p != name + length; ) { - ch = *p; - if (ch < 128) { - p++; - if (ch == '.' || ch == ';' || ch == '[' ) { - return false; // do not permit '.', ';', or '[' - } - if (type != LegalClass && ch == '/') { - return false; // do not permit '/' unless it's class name - } - if (type == LegalMethod && (ch == '<' || ch == '>')) { - return false; // do not permit '<' or '>' in method names - } - } else { - char* tmp_p = UTF8::next(p, &ch); - p = tmp_p; - } - } - return true; -} - - -// Take pointer to a string. Skip over the longest part of the string that could -// be taken as a fieldname. Allow '/' if slash_ok is true. -// Return a pointer to just past the fieldname. -// Return NULL if no fieldname at all was found, or in the case of slash_ok -// being true, we saw consecutive slashes (meaning we were looking for a -// qualified path but found something that was badly-formed). -char* ClassFileParser::skip_over_field_name(char* name, bool slash_ok, unsigned int length) { - char* p; - jchar ch; - jboolean last_is_slash = false; - jboolean not_first_ch = false; - - for (p = name; p != name + length; not_first_ch = true) { - char* old_p = p; - ch = *p; - if (ch < 128) { - p++; - // quick check for ascii - if ((ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (ch == '_' || ch == '$') || - (not_first_ch && ch >= '0' && ch <= '9')) { - last_is_slash = false; - continue; - } - if (slash_ok && ch == '/') { - if (last_is_slash) { - return NULL; // Don't permit consecutive slashes - } - last_is_slash = true; - continue; - } - } else { - jint unicode_ch; - char* tmp_p = UTF8::next_character(p, &unicode_ch); - p = tmp_p; - last_is_slash = false; - // Check if ch is Java identifier start or is Java identifier part - // 4672820: call java.lang.Character methods directly without generating separate tables. - EXCEPTION_MARK; - instanceKlassHandle klass (THREAD, SystemDictionary::Character_klass()); - - // return value - JavaValue result(T_BOOLEAN); - // Set up the arguments to isJavaIdentifierStart and isJavaIdentifierPart - JavaCallArguments args; - args.push_int(unicode_ch); - - // public static boolean isJavaIdentifierStart(char ch); - JavaCalls::call_static(&result, - klass, - vmSymbols::isJavaIdentifierStart_name(), - vmSymbols::int_bool_signature(), - &args, - THREAD); - - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; - return 0; - } - if (result.get_jboolean()) { - continue; - } - - if (not_first_ch) { - // public static boolean isJavaIdentifierPart(char ch); - JavaCalls::call_static(&result, - klass, - vmSymbols::isJavaIdentifierPart_name(), - vmSymbols::int_bool_signature(), - &args, - THREAD); - - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; - return 0; - } - - if (result.get_jboolean()) { - continue; - } - } - } - return (not_first_ch) ? old_p : NULL; - } - return (not_first_ch) ? p : NULL; -} - - -// Take pointer to a string. Skip over the longest part of the string that could -// be taken as a field signature. Allow "void" if void_ok. -// Return a pointer to just past the signature. -// Return NULL if no legal signature is found. -char* ClassFileParser::skip_over_field_signature(char* signature, - bool void_ok, - unsigned int length, - TRAPS) { - unsigned int array_dim = 0; - while (length > 0) { - switch (signature[0]) { - case JVM_SIGNATURE_VOID: if (!void_ok) { return NULL; } - case JVM_SIGNATURE_BOOLEAN: - case JVM_SIGNATURE_BYTE: - case JVM_SIGNATURE_CHAR: - case JVM_SIGNATURE_SHORT: - case JVM_SIGNATURE_INT: - case JVM_SIGNATURE_FLOAT: - case JVM_SIGNATURE_LONG: - case JVM_SIGNATURE_DOUBLE: - return signature + 1; - case JVM_SIGNATURE_CLASS: { - if (_major_version < JAVA_1_5_VERSION) { - // Skip over the class name if one is there - char* p = skip_over_field_name(signature + 1, true, --length); - - // The next character better be a semicolon - if (p && (p - signature) > 1 && p[0] == ';') { - return p + 1; - } - } else { - // 4900761: For class version > 48, any unicode is allowed in class name. - length--; - signature++; - while (length > 0 && signature[0] != ';') { - if (signature[0] == '.') { - classfile_parse_error("Class name contains illegal character '.' in descriptor in class file %s", CHECK_0); - } - length--; - signature++; - } - if (signature[0] == ';') { return signature + 1; } - } - - return NULL; - } - case JVM_SIGNATURE_ARRAY: - array_dim++; - if (array_dim > 255) { - // 4277370: array descriptor is valid only if it represents 255 or fewer dimensions. - classfile_parse_error("Array type descriptor has more than 255 dimensions in class file %s", CHECK_0); - } - // The rest of what's there better be a legal signature - signature++; - length--; - void_ok = false; - break; - - default: - return NULL; - } - } - return NULL; -} From 424ccf1771e1d182a55efe6fa21eae6a65e55cf9 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Fri, 24 Oct 2014 18:33:42 +0200 Subject: [PATCH 28/67] 8062070: com/sun/jdi/DoubleAgentTest.java.DoubleAgentTest fails intermittently after 8056143 Reviewed-by: dholmes --- jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java index 4698a078b78..290a8795c7e 100644 --- a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java @@ -319,13 +319,14 @@ public final class ProcessTools { return output; } catch (Throwable t) { + if (p != null) { + p.destroyForcibly().waitFor(); + } + failed = true; System.out.println("executeProcess() failed: " + t); throw t; } finally { - if (p != null) { - p.destroyForcibly().waitFor(); - } if (failed) { System.err.println(getProcessLog(pb, output)); } From b9c70becabf79fa5d0597f6ed5f780e4595618ff Mon Sep 17 00:00:00 2001 From: Andrey Zakharov Date: Mon, 27 Oct 2014 07:52:49 -0700 Subject: [PATCH 29/67] 8059614: [TESTBUG] Test for UseNUMA enable UseNUMAInterleaving Tests that UseNUMAInterleaving enabled for all collectors by ergonomics, on all platforms when UseNUMA feature is enabled. Reviewed-by: jmasa, dfazunen --- .../gc/arguments/TestUseNUMAInterleaving.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 hotspot/test/gc/arguments/TestUseNUMAInterleaving.java diff --git a/hotspot/test/gc/arguments/TestUseNUMAInterleaving.java b/hotspot/test/gc/arguments/TestUseNUMAInterleaving.java new file mode 100644 index 00000000000..edc6f9faf2f --- /dev/null +++ b/hotspot/test/gc/arguments/TestUseNUMAInterleaving.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, 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 TestUseNUMAInterleaving + * @summary Tests that UseNUMAInterleaving enabled for all collectors by + * ergonomics, on all platforms when UseNUMA feature is enabled. + * @bug 8059614 + * @key gc + * @library /testlibrary + * @run driver TestUseNUMAInterleaving + */ +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.OutputAnalyzer; + +public class TestUseNUMAInterleaving { + + public static void main(String[] args) throws Exception { + String[] vmargs = new String[]{ + "-XX:+UseNUMA", + "-XX:+PrintFlagsFinal", + "-version" + }; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, vmargs); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + boolean isNUMAEnabled + = Boolean.parseBoolean(output.firstMatch(NUMA_FLAG_PATTERN, 1)); + + if (isNUMAEnabled) { + output.shouldMatch("\\bUseNUMAInterleaving\\b.*?=.*?true"); + System.out.println(output.getStdout()); + } else { + System.out.println(output.firstMatch(NUMA_FLAG_PATTERN)); + System.out.println(output.firstMatch(NUMA_FLAG_PATTERN, 1)); + } + } + + private static final String NUMA_FLAG_PATTERN = "\\bUseNUMA\\b.*?=.*?([a-z]+)"; +} From 868afbd8bdff2f09d15a853e3b7e3bff1a9cac6c Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Mon, 27 Oct 2014 15:59:12 -0400 Subject: [PATCH 30/67] 8048124: Read hijra-config-umalqura.properties as a resource 8061533: HijrahChronology should use Integer.parseInt Removed use of calendar.properties to configure calendars, move UmmAlQura calendar to resource; minor cleanup using parseInt Reviewed-by: alanb, chegar --- jdk/make/copy/Copy-java.base.gmk | 16 -- jdk/make/profile-includes.txt | 2 - .../java/time/chrono/HijrahChronology.java | 163 +++++------------- ...hijrah-config-islamic-umalqura.properties} | 0 .../java/util/JapaneseImperialCalendar.java | 3 +- .../sun/util/calendar/CalendarSystem.java | 38 ---- .../java.base/share/conf/calendars.properties | 29 ---- 7 files changed, 44 insertions(+), 207 deletions(-) rename jdk/src/java.base/share/{conf/hijrah-config-umalqura.properties => classes/java/time/chrono/hijrah-config-islamic-umalqura.properties} (100%) delete mode 100644 jdk/src/java.base/share/conf/calendars.properties diff --git a/jdk/make/copy/Copy-java.base.gmk b/jdk/make/copy/Copy-java.base.gmk index 9ca554409a6..fd9a0ef3afa 100644 --- a/jdk/make/copy/Copy-java.base.gmk +++ b/jdk/make/copy/Copy-java.base.gmk @@ -48,22 +48,6 @@ $(INCLUDE_DST_OS_DIR)/%.h: \ ################################################################################ -CALENDARS_SRC := $(JDK_TOPDIR)/src/java.base/share/conf - -$(LIB_DST_DIR)/calendars.properties: $(CALENDARS_SRC)/calendars.properties - $(call install-file) - -BASE_CONF_FILES += $(LIB_DST_DIR)/calendars.properties - -$(LIB_DST_DIR)/hijrah-config-umalqura.properties: $(CALENDARS_SRC)/hijrah-config-umalqura.properties - $(MKDIR) -p $(@D) - $(RM) $@ - $(CP) $< $@ - -BASE_CONF_FILES += $(LIB_DST_DIR)/hijrah-config-umalqura.properties - -################################################################################ - ifneq ($(findstring $(OPENJDK_TARGET_OS), windows aix),) TZMAPPINGS_SRC := $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/conf diff --git a/jdk/make/profile-includes.txt b/jdk/make/profile-includes.txt index a3c79856e92..226b1ed9eb0 100644 --- a/jdk/make/profile-includes.txt +++ b/jdk/make/profile-includes.txt @@ -54,14 +54,12 @@ PROFILE_1_JRE_LIB_FILES := \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jvm$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jvm.diz \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/Xusage.txt \ - calendars.properties \ classlist \ ext/localedata.jar \ ext/meta-index \ ext/sunec.jar \ ext/sunjce_provider.jar \ ext/sunpkcs11.jar \ - hijrah-config-umalqura.properties \ jce.jar \ jsse.jar \ logging.properties \ diff --git a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java index 7c5005fbe9a..c6c6d4a2e8f 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java @@ -61,13 +61,14 @@ import static java.time.temporal.ChronoField.EPOCH_DAY; import java.io.File; import java.io.FileInputStream; +import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.Serializable; import java.security.AccessController; -import java.security.PrivilegedActionException; +import java.security.PrivilegedAction; import java.time.Clock; import java.time.DateTimeException; import java.time.Instant; @@ -145,29 +146,7 @@ import sun.util.logging.PlatformLogger; * property resource that defines the {@code ID}, the {@code calendar type}, * the start of the calendar, the alignment with the * ISO calendar, and the length of each month for a range of years. - * The variants are identified in the {@code calendars.properties} file. - * The new properties are prefixed with {@code "calendars.hijrah."}: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Property NameProperty valueDescription
calendars.hijrah.{ID}The property resource defining the {@code {ID}} variantThe property resource is located with the {@code calendars.properties} file
calendars.hijrah.{ID}.typeThe calendar typeLDML defines the calendar type names
+ * The variants are loaded by HijrahChronology as a resource from hijrah-config-.properties. *

* The Hijrah property resource is a set of properties that describe the calendar. * The syntax is defined by {@code java.util.Properties#load(Reader)}. @@ -279,91 +258,41 @@ public final class HijrahChronology extends AbstractChronology implements Serial * Computed by {@link #createEpochMonths}. */ private transient int maxYearLength; - /** - * A reference to the properties stored in - * ${java.home}/lib/calendars.properties - */ - private final transient static Properties calendarProperties; /** - * Prefix of property names for Hijrah calendar variants. + * Prefix of resource names for Hijrah calendar variants. */ - private static final String PROP_PREFIX = "calendar.hijrah."; - /** - * Suffix of property names containing the calendar type of a variant. - */ - private static final String PROP_TYPE_SUFFIX = ".type"; + private static final String RESOURCE_PREFIX = "hijrah-config-"; /** - * Static initialization of the predefined calendars found in the - * lib/calendars.properties file. + * Suffix of resource names for Hijrah calendar variants. + */ + private static final String RESOURCE_SUFFIX = ".properties"; + + /** + * Static initialization of the built-in calendars. + * The data is not loaded until it is used. */ static { - try { - calendarProperties = sun.util.calendar.BaseCalendar.getCalendarProperties(); - } catch (IOException ioe) { - throw new InternalError("Can't initialize lib/calendars.properties", ioe); - } - - try { - INSTANCE = new HijrahChronology("Hijrah-umalqura"); - // Register it by its aliases - AbstractChronology.registerChrono(INSTANCE, "Hijrah"); - AbstractChronology.registerChrono(INSTANCE, "islamic"); - } catch (DateTimeException ex) { - // Absence of Hijrah calendar is fatal to initializing this class. - PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono"); - logger.severe("Unable to initialize Hijrah calendar: Hijrah-umalqura", ex); - throw new RuntimeException("Unable to initialize Hijrah-umalqura calendar", ex.getCause()); - } - registerVariants(); + INSTANCE = new HijrahChronology("Hijrah-umalqura", "islamic-umalqura"); + // Register it by its aliases + AbstractChronology.registerChrono(INSTANCE, "Hijrah"); + AbstractChronology.registerChrono(INSTANCE, "islamic"); } /** - * For each Hijrah variant listed, create the HijrahChronology and register it. - * Exceptions during initialization are logged but otherwise ignored. - */ - private static void registerVariants() { - for (String name : calendarProperties.stringPropertyNames()) { - if (name.startsWith(PROP_PREFIX)) { - String id = name.substring(PROP_PREFIX.length()); - if (id.indexOf('.') >= 0) { - continue; // no name or not a simple name of a calendar - } - if (id.equals(INSTANCE.getId())) { - continue; // do not duplicate the default - } - try { - // Create and register the variant - HijrahChronology chrono = new HijrahChronology(id); - AbstractChronology.registerChrono(chrono); - } catch (DateTimeException ex) { - // Log error and continue - PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono"); - logger.severe("Unable to initialize Hijrah calendar: " + id, ex); - } - } - } - } - - /** - * Create a HijrahChronology for the named variant. - * The resource and calendar type are retrieved from properties - * in the {@code calendars.properties}. - * The property names are {@code "calendar.hijrah." + id} - * and {@code "calendar.hijrah." + id + ".type"} + * Create a HijrahChronology for the named variant and type. + * * @param id the id of the calendar - * @throws DateTimeException if the calendar type is missing from the properties file. - * @throws IllegalArgumentException if the id is empty + * @param calType the typeId of the calendar + * @throws IllegalArgumentException if the id or typeId is empty */ - private HijrahChronology(String id) throws DateTimeException { + private HijrahChronology(String id, String calType) { if (id.isEmpty()) { throw new IllegalArgumentException("calendar id is empty"); } - String propName = PROP_PREFIX + id + PROP_TYPE_SUFFIX; - String calType = calendarProperties.getProperty(propName); - if (calType == null || calType.isEmpty()) { - throw new DateTimeException("calendarType is missing or empty for: " + propName); + if (calType.isEmpty()) { + throw new IllegalArgumentException("calendar typeId is empty"); } this.typeId = id; this.calendarType = calType; @@ -866,30 +795,26 @@ public final class HijrahChronology extends AbstractChronology implements Serial /** * Return the configuration properties from the resource. *

- * The default location of the variant configuration resource is: + * The location of the variant configuration resource is: *

-     *   "$java.home/lib/" + resource-name
+     *   "/java/time/chrono/hijrah-config-" + calendarType + ".properties"
      * 
* - * @param resource the name of the calendar property resource + * @param calendarType the calendarType of the calendar variant * @return a Properties containing the properties read from the resource. * @throws Exception if access to the property resource fails */ - private static Properties readConfigProperties(final String resource) throws Exception { - try { - return AccessController - .doPrivileged((java.security.PrivilegedExceptionAction) - () -> { - String libDir = System.getProperty("java.home") + File.separator + "lib"; - File file = new File(libDir, resource); - Properties props = new Properties(); - try (InputStream is = new FileInputStream(file)) { - props.load(is); - } - return props; - }); - } catch (PrivilegedActionException pax) { - throw pax.getException(); + private Properties readConfigProperties(final String calendarType) throws Exception { + String resourceName = RESOURCE_PREFIX + calendarType + RESOURCE_SUFFIX; + PrivilegedAction getResourceAction = () -> HijrahChronology.class.getResourceAsStream(resourceName); + FilePermission perm = new FilePermission("<>", "read"); + try (InputStream is = AccessController.doPrivileged(getResourceAction, null, perm)) { + if (is == null) { + throw new RuntimeException("Hijrah calendar resource not found: /java/time/chrono/" + resourceName); + } + Properties props = new Properties(); + props.load(is); + return props; } } @@ -906,9 +831,7 @@ public final class HijrahChronology extends AbstractChronology implements Serial */ private void loadCalendarData() { try { - String resourceName = calendarProperties.getProperty(PROP_PREFIX + typeId); - Objects.requireNonNull(resourceName, "Resource missing for calendar: " + PROP_PREFIX + typeId); - Properties props = readConfigProperties(resourceName); + Properties props = readConfigProperties(calendarType); Map years = new HashMap<>(); int minYear = Integer.MAX_VALUE; @@ -937,7 +860,7 @@ public final class HijrahChronology extends AbstractChronology implements Serial default: try { // Everything else is either a year or invalid - int year = Integer.valueOf(key); + int year = Integer.parseInt(key); int[] months = parseMonths((String) entry.getValue()); years.put(year, months); maxYear = Math.max(maxYear, year); @@ -1045,7 +968,7 @@ public final class HijrahChronology extends AbstractChronology implements Serial } for (int i = 0; i < 12; i++) { try { - months[i] = Integer.valueOf(numbers[i]); + months[i] = Integer.parseInt(numbers[i]); } catch (NumberFormatException nfe) { throw new IllegalArgumentException("bad key: " + numbers[i]); } @@ -1067,9 +990,9 @@ public final class HijrahChronology extends AbstractChronology implements Serial throw new IllegalArgumentException("date must be yyyy-MM-dd"); } int[] ymd = new int[3]; - ymd[0] = Integer.valueOf(string.substring(0, 4)); - ymd[1] = Integer.valueOf(string.substring(5, 7)); - ymd[2] = Integer.valueOf(string.substring(8, 10)); + ymd[0] = Integer.parseInt(string, 0, 4, 10); + ymd[1] = Integer.parseInt(string, 5, 7, 10); + ymd[2] = Integer.parseInt(string, 8, 10, 10); return ymd; } catch (NumberFormatException ex) { throw new IllegalArgumentException("date must be yyyy-MM-dd", ex); diff --git a/jdk/src/java.base/share/conf/hijrah-config-umalqura.properties b/jdk/src/java.base/share/classes/java/time/chrono/hijrah-config-islamic-umalqura.properties similarity index 100% rename from jdk/src/java.base/share/conf/hijrah-config-umalqura.properties rename to jdk/src/java.base/share/classes/java/time/chrono/hijrah-config-islamic-umalqura.properties diff --git a/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java b/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java index 81b769af01f..c66518a5cc4 100644 --- a/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java +++ b/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java @@ -97,8 +97,7 @@ class JapaneseImperialCalendar extends Calendar { * * This implementation uses * sun.util.calendar.LocalGregorianCalendar to perform most of the - * calendar calculations. LocalGregorianCalendar is configurable - * and reads /lib/calendars.properties at the start-up. + * calendar calculations. */ /** diff --git a/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java b/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java index 589f552eb95..811eae7b441 100644 --- a/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java +++ b/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java @@ -177,44 +177,6 @@ public abstract class CalendarSystem { return (cs == null) ? cal : cs; } - /** - * Returns a {@link Properties} loaded from lib/calendars.properties. - * - * @return a {@link Properties} loaded from lib/calendars.properties - * @throws IOException if an error occurred when reading from the input stream - * @throws IllegalArgumentException if the input stream contains any malformed - * Unicode escape sequences - */ - public static Properties getCalendarProperties() throws IOException { - Properties calendarProps = null; - try { - String homeDir = AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("java.home")); - final String fname = homeDir + File.separator + "lib" + File.separator - + "calendars.properties"; - calendarProps = AccessController.doPrivileged(new PrivilegedExceptionAction() { - @Override - public Properties run() throws IOException { - Properties props = new Properties(); - try (FileInputStream fis = new FileInputStream(fname)) { - props.load(fis); - } - return props; - } - }); - } catch (PrivilegedActionException e) { - Throwable cause = e.getCause(); - if (cause instanceof IOException) { - throw (IOException) cause; - } else if (cause instanceof IllegalArgumentException) { - throw (IllegalArgumentException) cause; - } - // Should not happen - throw new InternalError(cause); - } - return calendarProps; - } - //////////////////////////////// Calendar API ////////////////////////////////// /** diff --git a/jdk/src/java.base/share/conf/calendars.properties b/jdk/src/java.base/share/conf/calendars.properties deleted file mode 100644 index 46bb0e2bd60..00000000000 --- a/jdk/src/java.base/share/conf/calendars.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2005, 2014, 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. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# 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. -# - -# -# Hijrah calendars -# -calendar.hijrah.Hijrah-umalqura: hijrah-config-umalqura.properties -calendar.hijrah.Hijrah-umalqura.type: islamic-umalqura From 1457a8cc935f0afdf31e656db8ae00e3f45125a0 Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Mon, 27 Oct 2014 16:57:59 -0400 Subject: [PATCH 31/67] 8062198: Add RowSetMetaDataImpl Tests and add column range validation to isdefinitlyWritable Reviewed-by: joehw --- .../javax/sql/rowset/RowSetMetaDataImpl.java | 6 +- jdk/test/java/sql/util/BaseTest.java | 27 + jdk/test/java/sql/util/StubBlob.java | 73 --- jdk/test/javax/sql/testng/TEST.properties | 1 + .../test/rowset/RowSetMetaDataTests.java | 555 ++++++++++++++++++ jdk/test/javax/sql/testng/util/BaseTest.java | 99 ---- .../javax/sql/testng/util/TestPolicy.java | 135 ----- 7 files changed, 587 insertions(+), 309 deletions(-) delete mode 100644 jdk/test/java/sql/util/StubBlob.java create mode 100644 jdk/test/javax/sql/testng/test/rowset/RowSetMetaDataTests.java delete mode 100644 jdk/test/javax/sql/testng/util/BaseTest.java delete mode 100644 jdk/test/javax/sql/testng/util/TestPolicy.java diff --git a/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java b/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java index 832b6512987..a1230a2da73 100644 --- a/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java +++ b/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java @@ -803,8 +803,10 @@ public class RowSetMetaDataImpl implements RowSetMetaData, Serializable { * @throws SQLException if a database access error occurs * or the given column number is out of bounds */ - public boolean isDefinitelyWritable(int columnIndex) - throws SQLException { return true;} + public boolean isDefinitelyWritable(int columnIndex) throws SQLException { + checkColRange(columnIndex); + return true; + } /** * Retrieves the fully-qualified name of the class in the Java diff --git a/jdk/test/java/sql/util/BaseTest.java b/jdk/test/java/sql/util/BaseTest.java index da991431abc..6821940b7ce 100644 --- a/jdk/test/java/sql/util/BaseTest.java +++ b/jdk/test/java/sql/util/BaseTest.java @@ -28,11 +28,13 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.security.Policy; +import java.sql.JDBCType; import java.sql.SQLException; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; public class BaseTest { @@ -96,4 +98,29 @@ public class BaseTest { protected static void setPolicy(Policy p) { Policy.setPolicy(p); } + + /* + * DataProvider used to specify the value to set and check for + * methods using boolean values + */ + @DataProvider(name = "trueFalse") + protected Object[][] trueFalse() { + return new Object[][]{ + {true}, + {false} + }; + } + + /* + * DataProvider used to specify the standard JDBC Types + */ + @DataProvider(name = "jdbcTypes") + protected Object[][] jdbcTypes() { + Object[][] o = new Object[JDBCType.values().length][1]; + int pos = 0; + for (JDBCType c : JDBCType.values()) { + o[pos++][0] = c.getVendorTypeNumber(); + } + return o; + } } diff --git a/jdk/test/java/sql/util/StubBlob.java b/jdk/test/java/sql/util/StubBlob.java deleted file mode 100644 index 59917c7094f..00000000000 --- a/jdk/test/java/sql/util/StubBlob.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ -package util; - -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.Blob; -import java.sql.SQLException; - - -public class StubBlob implements Blob { - public long length() throws SQLException { - return 0; - } - public byte[] getBytes(long pos, int length) - throws SQLException { - return null; - } - public InputStream getBinaryStream() - throws SQLException { - return null; - } - public long position(byte[] pattern, long start) - throws SQLException { - return 0; - } - public long position(Blob pattern, long start) - throws SQLException { - return 0; - } - public int setBytes(long pos, byte[] bytes) - throws SQLException { - return 0; - } - public int setBytes(long pos, byte[] bytes, int offset, int len) - throws SQLException { - return 0; - } - public OutputStream setBinaryStream(long pos) - throws SQLException { - return null; - } - public void truncate(long len) - throws SQLException { - } - /* 6.0 implementation */ - - public void free() throws SQLException {} - - public InputStream getBinaryStream(long pos, long length) throws SQLException { - return null; - } -} diff --git a/jdk/test/javax/sql/testng/TEST.properties b/jdk/test/javax/sql/testng/TEST.properties index ded0fc780a3..6959dd476fd 100644 --- a/jdk/test/javax/sql/testng/TEST.properties +++ b/jdk/test/javax/sql/testng/TEST.properties @@ -1,3 +1,4 @@ # JDBC unit tests uses TestNG TestNG.dirs= . othervm.dirs= . +lib.dirs = /java/sql/ diff --git a/jdk/test/javax/sql/testng/test/rowset/RowSetMetaDataTests.java b/jdk/test/javax/sql/testng/test/rowset/RowSetMetaDataTests.java new file mode 100644 index 00000000000..8a944a8bbb1 --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/RowSetMetaDataTests.java @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2014, 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. + */ +package test.rowset; + +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Types; +import javax.sql.RowSetMetaData; +import javax.sql.rowset.RowSetMetaDataImpl; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import util.BaseTest; + +public class RowSetMetaDataTests extends BaseTest { + + // Max columns used in the tests + private final int MAX_COLUMNS = 5; + // Instance to be used within the tests + private RowSetMetaDataImpl rsmd; + + @BeforeMethod + public void setUpMethod() throws Exception { + rsmd = new RowSetMetaDataImpl(); + rsmd.setColumnCount(MAX_COLUMNS); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test(Integer col) throws Exception { + rsmd.getCatalogName(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test01(Integer col) throws Exception { + rsmd.getColumnClassName(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test02(Integer col) throws Exception { + rsmd.getColumnDisplaySize(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test03(Integer col) throws Exception { + rsmd.getColumnLabel(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test04(Integer col) throws Exception { + rsmd.getColumnName(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test05(Integer col) throws Exception { + rsmd.getColumnType(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test06(Integer col) throws Exception { + rsmd.getColumnTypeName(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test07(Integer col) throws Exception { + rsmd.getPrecision(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test08(Integer col) throws Exception { + rsmd.getScale(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test09(Integer col) throws Exception { + rsmd.getSchemaName(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test10(Integer col) throws Exception { + rsmd.getTableName(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test11(Integer col) throws Exception { + rsmd.isAutoIncrement(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test12(Integer col) throws Exception { + rsmd.isCaseSensitive(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test13(Integer col) throws Exception { + rsmd.isCurrency(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test14(Integer col) throws Exception { + rsmd.isDefinitelyWritable(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test15(Integer col) throws Exception { + rsmd.isNullable(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test16(Integer col) throws Exception { + rsmd.isReadOnly(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test17(Integer col) throws Exception { + rsmd.isSearchable(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test18(Integer col) throws Exception { + rsmd.isSigned(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test19(Integer col) throws Exception { + rsmd.isWritable(col); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test20(Integer col) throws Exception { + rsmd.setAutoIncrement(col, true); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test21(Integer col) throws Exception { + rsmd.setCaseSensitive(col, true); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test22(Integer col) throws Exception { + rsmd.setCatalogName(col, null); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test23(Integer col) throws Exception { + rsmd.setColumnDisplaySize(col, 5); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test24(Integer col) throws Exception { + rsmd.setColumnLabel(col, "label"); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test25(Integer col) throws Exception { + rsmd.setColumnName(col, "F1"); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test26(Integer col) throws Exception { + rsmd.setColumnType(col, Types.CHAR); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test27(Integer col) throws Exception { + rsmd.setColumnTypeName(col, "F1"); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test28(Integer col) throws Exception { + rsmd.setCurrency(col, true); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test29(Integer col) throws Exception { + rsmd.setNullable(col, ResultSetMetaData.columnNoNulls); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test30(Integer col) throws Exception { + rsmd.setPrecision(col, 2); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test31(Integer col) throws Exception { + rsmd.setScale(col, 2); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test32(Integer col) throws Exception { + rsmd.setSchemaName(col, "Gotham"); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test33(Integer col) throws Exception { + rsmd.setSearchable(col, false); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test34(Integer col) throws Exception { + rsmd.setSigned(col, false); + } + + /* + * Validate a SQLException is thrown for an invalid column index + */ + @Test(dataProvider = "invalidColumnRanges", + expectedExceptions = SQLException.class) + public void test35(Integer col) throws Exception { + rsmd.setTableName(col, "SUPERHEROS"); + } + + /* + * Validate that the correct class name is returned for the column + * Note: Once setColumnClassName is added to RowSetMetaData, this + * method will need to change. + */ + @Test(dataProvider = "columnClassNames") + public void test36(Integer type, String name) throws Exception { + rsmd.setColumnType(1, type); + assertTrue(rsmd.getColumnClassName(1).equals(name)); + } + + /* + * Validate that all of the methods are accessible and the correct value + * is returned for each column + */ + @Test(dataProvider = "columnRanges") + public void test37(Integer col) throws Exception { + rsmd.setAutoIncrement(col, true); + assertTrue(rsmd.isAutoIncrement(col)); + rsmd.setCaseSensitive(col, true); + assertTrue(rsmd.isCaseSensitive(col)); + rsmd.setCatalogName(col, "Gotham"); + assertTrue(rsmd.getCatalogName(col).equals("Gotham")); + rsmd.setColumnDisplaySize(col, 20); + assertTrue(rsmd.getColumnDisplaySize(col) == 20); + rsmd.setColumnLabel(col, "F1"); + assertTrue(rsmd.getColumnLabel(col).equals("F1")); + rsmd.setColumnName(col, "F1"); + assertTrue(rsmd.getColumnName(col).equals("F1")); + rsmd.setColumnType(col, Types.INTEGER); + assertTrue(rsmd.getColumnType(col) == Types.INTEGER); + assertTrue(rsmd.getColumnClassName(col).equals(Integer.class.getName())); + rsmd.setColumnTypeName(col, "INTEGER"); + assertTrue(rsmd.getColumnTypeName(col).equals("INTEGER")); + rsmd.setCurrency(col, true); + assertTrue(rsmd.isCurrency(col)); + rsmd.setNullable(col, ResultSetMetaData.columnNoNulls); + assertTrue(rsmd.isNullable(col) == ResultSetMetaData.columnNoNulls); + rsmd.setPrecision(col, 2); + assertTrue(rsmd.getPrecision(col) == 2); + rsmd.setScale(col, 2); + assertTrue(rsmd.getScale(col) == 2); + rsmd.setSchemaName(col, "GOTHAM"); + assertTrue(rsmd.getSchemaName(col).equals("GOTHAM")); + rsmd.setSearchable(col, false); + assertFalse(rsmd.isSearchable(col)); + rsmd.setSigned(col, false); + assertFalse(rsmd.isSigned(col)); + rsmd.setTableName(col, "SUPERHEROS"); + assertTrue(rsmd.getTableName(col).equals("SUPERHEROS")); + rsmd.isReadOnly(col); + rsmd.isDefinitelyWritable(col); + rsmd.isWritable(col); + + } + + /* + * Validate that the proper values are accepted by setNullable + */ + @Test(dataProvider = "validSetNullableValues") + public void test38(Integer val) throws Exception { + rsmd.setNullable(1, val); + } + + /* + * Validate that the correct type is returned for the column + */ + @Test(dataProvider = "jdbcTypes") + public void test39(Integer type) throws Exception { + rsmd.setColumnType(1, type); + assertTrue(type == rsmd.getColumnType(1)); + } + + /* + * Validate that the correct value is returned from the isXXX methods + */ + @Test(dataProvider = "trueFalse") + public void test40(Boolean b) throws Exception { + rsmd.setAutoIncrement(1, b); + rsmd.setCaseSensitive(1, b); + rsmd.setCurrency(1, b); + rsmd.setSearchable(1, b); + rsmd.setSigned(1, b); + assertTrue(rsmd.isAutoIncrement(1) == b); + assertTrue(rsmd.isCaseSensitive(1) == b); + assertTrue(rsmd.isCurrency(1) == b); + assertTrue(rsmd.isSearchable(1) == b); + assertTrue(rsmd.isSigned(1) == b); + } + + /* + * Validate isWrapperFor and unwrap work correctly + */ + @SuppressWarnings("unchecked") + @Test + public void test99() throws Exception { + RowSetMetaData rsmd1 = rsmd; + ResultSetMetaData rsmd2 = rsmd; + Class clzz = rsmd.getClass(); + assertTrue(rsmd1.isWrapperFor(clzz)); + assertTrue(rsmd2.isWrapperFor(clzz)); + RowSetMetaDataImpl rsmdi = (RowSetMetaDataImpl) rsmd2.unwrap(clzz); + + // False should be returned + assertFalse(rsmd1.isWrapperFor(this.getClass())); + assertFalse(rsmd2.isWrapperFor(this.getClass())); + } + + /* + * DataProvider used to provide Date which are not valid and are used + * to validate that an IllegalArgumentException will be thrown from the + * valueOf method + */ + @DataProvider(name = "validSetNullableValues") + private Object[][] validSetNullableValues() { + return new Object[][]{ + {ResultSetMetaData.columnNoNulls}, + {ResultSetMetaData.columnNullable}, + {ResultSetMetaData.columnNullableUnknown} + }; + } + + /* + * DataProvider used to provide column indexes that are out of range so that + * SQLException is thrown + */ + @DataProvider(name = "invalidColumnRanges") + private Object[][] invalidColumnRanges() { + return new Object[][]{ + {-1}, + {0}, + {MAX_COLUMNS + 1} + }; + } + + /* + * DataProvider used to provide the valid column ranges for the + * RowSetMetaDataImpl object + */ + @DataProvider(name = "columnRanges") + private Object[][] columnRanges() { + Object[][] o = new Object[MAX_COLUMNS][1]; + for (int i = 1; i <= MAX_COLUMNS; i++) { + o[i - 1][0] = i; + } + return o; + } + + /* + * DataProvider used to specify the value to set via setColumnType and + * the expected value to be returned from getColumnClassName + */ + @DataProvider(name = "columnClassNames") + private Object[][] columnClassNames() { + return new Object[][]{ + {Types.CHAR, "java.lang.String"}, + {Types.NCHAR, "java.lang.String"}, + {Types.VARCHAR, "java.lang.String"}, + {Types.NVARCHAR, "java.lang.String"}, + {Types.LONGVARCHAR, "java.lang.String"}, + {Types.LONGNVARCHAR, "java.lang.String"}, + {Types.NUMERIC, "java.math.BigDecimal"}, + {Types.DECIMAL, "java.math.BigDecimal"}, + {Types.BIT, "java.lang.Boolean"}, + {Types.TINYINT, "java.lang.Byte"}, + {Types.SMALLINT, "java.lang.Short"}, + {Types.INTEGER, "java.lang.Integer"}, + {Types.FLOAT, "java.lang.Double"}, + {Types.DOUBLE, "java.lang.Double"}, + {Types.BINARY, "byte[]"}, + {Types.VARBINARY, "byte[]"}, + {Types.LONGVARBINARY, "byte[]"}, + {Types.DATE, "java.sql.Date"}, + {Types.TIME, "java.sql.Time"}, + {Types.TIMESTAMP, "java.sql.Timestamp"}, + {Types.CLOB, "java.sql.Clob"}, + {Types.BLOB, "java.sql.Blob"} + + }; + + } + +} diff --git a/jdk/test/javax/sql/testng/util/BaseTest.java b/jdk/test/javax/sql/testng/util/BaseTest.java deleted file mode 100644 index da991431abc..00000000000 --- a/jdk/test/javax/sql/testng/util/BaseTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ -package util; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.security.Policy; -import java.sql.SQLException; -import org.testng.annotations.AfterClass; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; - -public class BaseTest { - - protected final String reason = "reason"; - protected final String state = "SQLState"; - protected final String cause = "java.lang.Throwable: cause"; - protected final Throwable t = new Throwable("cause"); - protected final Throwable t1 = new Throwable("cause 1"); - protected final Throwable t2 = new Throwable("cause 2"); - protected final int errorCode = 21; - protected final String[] msgs = {"Exception 1", "cause 1", "Exception 2", - "Exception 3", "cause 2"}; - - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @BeforeMethod - public void setUpMethod() throws Exception { - } - - @AfterMethod - public void tearDownMethod() throws Exception { - } - - /* - * Take some form of SQLException, serialize and deserialize it - */ - @SuppressWarnings("unchecked") - protected T - createSerializedException(T ex) - throws IOException, ClassNotFoundException { - return (T) serializeDeserializeObject(ex); - } - - /* - * Utility method to serialize and deserialize an object - */ - @SuppressWarnings("unchecked") - protected T serializeDeserializeObject(T o) - throws IOException, ClassNotFoundException { - T o1; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { - oos.writeObject(o); - } - try (ObjectInputStream ois - = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { - o1 = (T) ois.readObject(); - } - return o1; - } - - /* - * Utility Method used to set the current Policy - */ - protected static void setPolicy(Policy p) { - Policy.setPolicy(p); - } -} diff --git a/jdk/test/javax/sql/testng/util/TestPolicy.java b/jdk/test/javax/sql/testng/util/TestPolicy.java deleted file mode 100644 index dca2152deaa..00000000000 --- a/jdk/test/javax/sql/testng/util/TestPolicy.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ -package util; - -import java.io.FilePermission; -import java.security.AllPermission; -import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.security.Policy; -import java.security.ProtectionDomain; -import java.security.SecurityPermission; -import java.sql.SQLPermission; -import java.util.Enumeration; -import java.util.PropertyPermission; -import java.util.StringJoiner; - -/* - * Simple Policy class that supports the required Permissions to validate the - * JDBC concrete classes - */ -public class TestPolicy extends Policy { - - final PermissionCollection permissions = new Permissions(); - - /** - * Constructor which sets the minimum permissions allowing testNG to work - * with a SecurityManager - */ - public TestPolicy() { - setMinimalPermissions(); - } - - /* - * Constructor which determines which permissions are defined for this - * Policy used by the JDBC tests Possible values are: all (ALLPermissions), - * setLog (SQLPemission("setLog"), deregisterDriver - * (SQLPermission("deregisterDriver") (SQLPermission("deregisterDriver"), - * and setSyncFactory(SQLPermission(setSyncFactory), - * - * @param policy Permissions to set - */ - public TestPolicy(String policy) { - - switch (policy) { - case "all": - permissions.add(new AllPermission()); - break; - case "setLog": - setMinimalPermissions(); - permissions.add(new SQLPermission("setLog")); - break; - case "deregisterDriver": - setMinimalPermissions(); - permissions.add(new SQLPermission("deregisterDriver")); - break; - case "setSyncFactory": - setMinimalPermissions(); - permissions.add(new SQLPermission("setSyncFactory")); - break; - default: - setMinimalPermissions(); - } - } - - /* - * Defines the minimal permissions required by testNG when running these - * tests - */ - private void setMinimalPermissions() { - permissions.add(new SecurityPermission("getPolicy")); - permissions.add(new SecurityPermission("setPolicy")); - permissions.add(new RuntimePermission("getClassLoader")); - permissions.add(new RuntimePermission("setSecurityManager")); - permissions.add(new RuntimePermission("createSecurityManager")); - permissions.add(new PropertyPermission("testng.show.stack.frames", - "read")); - permissions.add(new PropertyPermission("line.separator", "read")); - permissions.add(new PropertyPermission("fileStringBuffer", "read")); - permissions.add(new PropertyPermission("dataproviderthreadcount", "read")); - permissions.add(new PropertyPermission("java.io.tmpdir", "read")); - permissions.add(new FilePermission("<>", - "read, write, delete")); - } - - /* - * Overloaded methods from the Policy class - */ - @Override - public String toString() { - StringJoiner sj = new StringJoiner("\n", "policy: ", ""); - Enumeration perms = permissions.elements(); - while (perms.hasMoreElements()) { - sj.add(perms.nextElement().toString()); - } - return sj.toString(); - - } - - @Override - public PermissionCollection getPermissions(ProtectionDomain domain) { - return permissions; - } - - @Override - public PermissionCollection getPermissions(CodeSource codesource) { - return permissions; - } - - @Override - public boolean implies(ProtectionDomain domain, Permission perm) { - return permissions.implies(perm); - } -} From a76f56165c557c1ec1ef189244ad03567736c06a Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Mon, 27 Oct 2014 13:45:39 -0700 Subject: [PATCH 32/67] 8043277: Update jdk regression tests to extend the default security policy instead of override Reviewed-by: alanb, mullan, chegar, sla --- jdk/test/TEST.ROOT | 3 + jdk/test/java/net/URLPermission/URLTest.java | 6 +- jdk/test/java/net/URLPermission/policy.1 | 57 ------------------ jdk/test/java/net/URLPermission/policy.2 | 57 ------------------ jdk/test/java/net/URLPermission/policy.3 | 58 ------------------- .../activateFails/ActivateFails.java | 2 +- .../activateFails/security.policy | 4 -- .../StubClassesPermitted.java | 2 +- .../stubClassesPermitted/security.policy | 4 -- jdk/test/java/security/KeyRep/Serial.java | 2 +- jdk/test/java/security/KeyRep/Serial.policy | 9 --- .../java/security/KeyRep/SerialDSAPubKey.java | 2 +- jdk/test/java/security/KeyRep/SerialOld.java | 2 +- .../java/security/KeyRep/SerialOld.policy | 52 ----------------- .../removing/RemoveStaticProvider.java | 2 +- .../removing/RemoveStaticProvider.policy | 10 ---- jdk/test/jdk/nio/zipfs/Basic.java | 2 +- jdk/test/jdk/nio/zipfs/PathOps.java | 2 +- jdk/test/jdk/nio/zipfs/ZFSTests.java | 2 +- jdk/test/jdk/nio/zipfs/ZipFSTester.java | 2 +- jdk/test/jdk/nio/zipfs/test.policy | 6 -- jdk/test/jdk/nio/zipfs/test.policy.readonly | 6 -- .../sun/security/pkcs11/KeyStore/Basic.policy | 14 ----- .../sun/security/pkcs11/Provider/Login.policy | 18 +----- 24 files changed, 17 insertions(+), 307 deletions(-) diff --git a/jdk/test/TEST.ROOT b/jdk/test/TEST.ROOT index 58a91d89a03..6df529bccbd 100644 --- a/jdk/test/TEST.ROOT +++ b/jdk/test/TEST.ROOT @@ -12,3 +12,6 @@ exclusiveAccess.dirs=java/rmi/Naming java/util/prefs sun/management/jmxremote su # Group definitions groups=TEST.groups [closed/TEST.groups] + +# Tests using jtreg 4.1 b10 features +requiredVersion=4.1 b10 diff --git a/jdk/test/java/net/URLPermission/URLTest.java b/jdk/test/java/net/URLPermission/URLTest.java index ceb0d2c8aeb..266fdfd0a89 100644 --- a/jdk/test/java/net/URLPermission/URLTest.java +++ b/jdk/test/java/net/URLPermission/URLTest.java @@ -29,11 +29,11 @@ import java.net.URLPermission; * @bug 8010464 * @library /lib/testlibrary/ * @build jdk.testlibrary.SimpleSSLContext - * @run main/othervm/policy=policy.1 URLTest one + * @run main/othervm/java.security.policy=policy.1 URLTest one * @run main/othervm URLTest one - * @run main/othervm/policy=policy.2 URLTest two + * @run main/othervm/java.security.policy=policy.2 URLTest two * @run main/othervm URLTest two - * @run main/othervm/policy=policy.3 URLTest three + * @run main/othervm/java.security.policy=policy.3 URLTest three * @run main/othervm URLTest three */ diff --git a/jdk/test/java/net/URLPermission/policy.1 b/jdk/test/java/net/URLPermission/policy.1 index 93439790658..fc0a6a6a04c 100644 --- a/jdk/test/java/net/URLPermission/policy.1 +++ b/jdk/test/java/net/URLPermission/policy.1 @@ -37,60 +37,3 @@ grant { permission "java.util.PropertyPermission" "test.src.path", "read"; }; -// Normal permissions that aren't granted when run under jtreg -grant codeBase "file:${java.home}/lib/ext/ucrypto.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; - permission java.lang.RuntimePermission "loadLibrary.j2ucrypto"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.OracleUcrypto"; - permission java.security.SecurityPermission "clearProviderProperties.OracleUcrypto"; - permission java.security.SecurityPermission "removeProviderProperty.OracleUcrypto"; - permission java.io.FilePermission "${java.home}/lib/security/ucrypto-solaris.cfg", "read"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunec.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "loadLibrary.sunec"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunEC"; - permission java.security.SecurityPermission "clearProviderProperties.SunEC"; - permission java.security.SecurityPermission "removeProviderProperty.SunEC"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunjce_provider.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.misc"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunJCE"; - permission java.security.SecurityPermission "clearProviderProperties.SunJCE"; - permission java.security.SecurityPermission "removeProviderProperty.SunJCE"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunpkcs11.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; - permission java.lang.RuntimePermission "loadLibrary.j2pkcs11"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.*"; - permission java.security.SecurityPermission "clearProviderProperties.*"; - permission java.security.SecurityPermission "removeProviderProperty.*"; - permission java.security.SecurityPermission "getProperty.auth.login.defaultCallbackHandler"; - permission java.security.SecurityPermission "authProvider.*"; - // Needed for reading PKCS11 config file and NSS library check - permission java.io.FilePermission "<>", "read"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunmscapi.jar" { - Permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "loadLibrary.sunmscapi"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunMSCAPI"; - permission java.security.SecurityPermission "clearProviderProperties.SunMSCAPI"; - permission java.security.SecurityPermission "removeProviderProperty.SunMSCAPI"; -}; - -grant codeBase "file:${{java.home}}/jre/lib/rt.jar" { - permission java.security.AllPermission; -}; - diff --git a/jdk/test/java/net/URLPermission/policy.2 b/jdk/test/java/net/URLPermission/policy.2 index 43ee0f204a8..745639ee2c0 100644 --- a/jdk/test/java/net/URLPermission/policy.2 +++ b/jdk/test/java/net/URLPermission/policy.2 @@ -37,60 +37,3 @@ grant { permission "java.util.PropertyPermission" "test.src.path", "read"; }; -// Normal permissions that aren't granted when run under jtreg -grant codeBase "file:${java.home}/lib/ext/ucrypto.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; - permission java.lang.RuntimePermission "loadLibrary.j2ucrypto"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.OracleUcrypto"; - permission java.security.SecurityPermission "clearProviderProperties.OracleUcrypto"; - permission java.security.SecurityPermission "removeProviderProperty.OracleUcrypto"; - permission java.io.FilePermission "${java.home}/lib/security/ucrypto-solaris.cfg", "read"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunec.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "loadLibrary.sunec"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunEC"; - permission java.security.SecurityPermission "clearProviderProperties.SunEC"; - permission java.security.SecurityPermission "removeProviderProperty.SunEC"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunjce_provider.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.misc"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunJCE"; - permission java.security.SecurityPermission "clearProviderProperties.SunJCE"; - permission java.security.SecurityPermission "removeProviderProperty.SunJCE"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunpkcs11.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; - permission java.lang.RuntimePermission "loadLibrary.j2pkcs11"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.*"; - permission java.security.SecurityPermission "clearProviderProperties.*"; - permission java.security.SecurityPermission "removeProviderProperty.*"; - permission java.security.SecurityPermission "getProperty.auth.login.defaultCallbackHandler"; - permission java.security.SecurityPermission "authProvider.*"; - // Needed for reading PKCS11 config file and NSS library check - permission java.io.FilePermission "<>", "read"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunmscapi.jar" { - Permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "loadLibrary.sunmscapi"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunMSCAPI"; - permission java.security.SecurityPermission "clearProviderProperties.SunMSCAPI"; - permission java.security.SecurityPermission "removeProviderProperty.SunMSCAPI"; -}; - -grant codeBase "file:///export/repos/jdk8/build/linux-x86_64-normal-server-fastdebug/images/j2sdk-image/jre/lib/rt.jar" { - permission java.security.AllPermission; -}; - diff --git a/jdk/test/java/net/URLPermission/policy.3 b/jdk/test/java/net/URLPermission/policy.3 index 54ddb2a591c..de0268f94e4 100644 --- a/jdk/test/java/net/URLPermission/policy.3 +++ b/jdk/test/java/net/URLPermission/policy.3 @@ -36,61 +36,3 @@ grant { permission "java.lang.RuntimePermission" "setFactory"; permission "java.util.PropertyPermission" "test.src.path", "read"; }; - -// Normal permissions that aren't granted when run under jtreg -grant codeBase "file:${java.home}/lib/ext/ucrypto.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; - permission java.lang.RuntimePermission "loadLibrary.j2ucrypto"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.OracleUcrypto"; - permission java.security.SecurityPermission "clearProviderProperties.OracleUcrypto"; - permission java.security.SecurityPermission "removeProviderProperty.OracleUcrypto"; - permission java.io.FilePermission "${java.home}/lib/security/ucrypto-solaris.cfg", "read"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunec.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "loadLibrary.sunec"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunEC"; - permission java.security.SecurityPermission "clearProviderProperties.SunEC"; - permission java.security.SecurityPermission "removeProviderProperty.SunEC"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunjce_provider.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.misc"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunJCE"; - permission java.security.SecurityPermission "clearProviderProperties.SunJCE"; - permission java.security.SecurityPermission "removeProviderProperty.SunJCE"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunpkcs11.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; - permission java.lang.RuntimePermission "loadLibrary.j2pkcs11"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.*"; - permission java.security.SecurityPermission "clearProviderProperties.*"; - permission java.security.SecurityPermission "removeProviderProperty.*"; - permission java.security.SecurityPermission "getProperty.auth.login.defaultCallbackHandler"; - permission java.security.SecurityPermission "authProvider.*"; - // Needed for reading PKCS11 config file and NSS library check - permission java.io.FilePermission "<>", "read"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunmscapi.jar" { - Permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "loadLibrary.sunmscapi"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunMSCAPI"; - permission java.security.SecurityPermission "clearProviderProperties.SunMSCAPI"; - permission java.security.SecurityPermission "removeProviderProperty.SunMSCAPI"; -}; - -grant codeBase "file:${{java.home}}/jre/lib/rt.jar" { - permission java.security.AllPermission; -}; - diff --git a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java index 08db49cb46b..6a2eba05864 100644 --- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java +++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java @@ -33,7 +33,7 @@ * @library ../../../testlibrary * @build TestLibrary RMID ActivationLibrary * ActivateMe ActivateFails_Stub ShutdownThread - * @run main/othervm/policy=security.policy/timeout=240 ActivateFails + * @run main/othervm/java.security.policy=security.policy/timeout=240 ActivateFails */ import java.rmi.*; diff --git a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/security.policy b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/security.policy index a66e2347ace..572e29ce309 100644 --- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/security.policy +++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/security.policy @@ -2,10 +2,6 @@ * security policy used by the test process */ -grant codeBase "file:${java.home}/lib/ext/*" { - permission java.security.AllPermission; -}; - grant { // standard test activation permissions permission java.io.FilePermission "..${/}..${/}test.props", "read"; diff --git a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java index d987f93b238..b7890e0ebe7 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java @@ -29,7 +29,7 @@ * @library ../../../testlibrary * @build TestLibrary RMID ActivationLibrary * CanCreateStubs StubClassesPermitted_Stub - * @run main/othervm/policy=security.policy/secure=java.lang.SecurityManager/timeout=240 StubClassesPermitted + * @run main/othervm/java.security.policy=security.policy/secure=java.lang.SecurityManager/timeout=240 StubClassesPermitted */ import java.io.*; diff --git a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/security.policy b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/security.policy index bb87a804b55..9287c5130c9 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/security.policy +++ b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/security.policy @@ -2,10 +2,6 @@ * security policy used by the test process */ -grant codeBase "file:${java.home}/lib/ext/*" { - permission java.security.AllPermission; -}; - grant { // standard test activation permissions permission java.io.FilePermission "..${/}..${/}test.props", "read"; diff --git a/jdk/test/java/security/KeyRep/Serial.java b/jdk/test/java/security/KeyRep/Serial.java index 8c3cd69d3e4..39b0ab42893 100644 --- a/jdk/test/java/security/KeyRep/Serial.java +++ b/jdk/test/java/security/KeyRep/Serial.java @@ -26,7 +26,7 @@ * @bug 4532506 4999599 * @summary Serializing KeyPair on one VM (Sun), * and Deserializing on another (IBM) fails - * @run main/othervm/policy=Serial.policy Serial + * @run main/othervm/java.security.policy=Serial.policy Serial */ import java.io.*; diff --git a/jdk/test/java/security/KeyRep/Serial.policy b/jdk/test/java/security/KeyRep/Serial.policy index b538d57b791..0c2c1d0868d 100644 --- a/jdk/test/java/security/KeyRep/Serial.policy +++ b/jdk/test/java/security/KeyRep/Serial.policy @@ -1,12 +1,3 @@ -grant codeBase "file:${java.home}/lib/ext/sunjce_provider.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.misc"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunJCE"; - permission java.security.SecurityPermission "clearProviderProperties.SunJCE"; - permission java.security.SecurityPermission "removeProviderProperty.SunJCE"; -}; - grant { // XXX note package access is *not* granted to the 'sun' package }; diff --git a/jdk/test/java/security/KeyRep/SerialDSAPubKey.java b/jdk/test/java/security/KeyRep/SerialDSAPubKey.java index e29b4e94d47..41f06cff08d 100644 --- a/jdk/test/java/security/KeyRep/SerialDSAPubKey.java +++ b/jdk/test/java/security/KeyRep/SerialDSAPubKey.java @@ -26,7 +26,7 @@ * @bug 6232513 * @summary RMI interoperability issue with DSAPublicKey obj between * JDK1.4 & JDK1.5 - * @run main/othervm/policy=SerialDSAPubKey.policy -Dsun.security.key.serial.interop=true -Dsun.security.pkcs11.enable-solaris=false SerialDSAPubKey + * @run main/othervm/java.security.policy=SerialDSAPubKey.policy -Dsun.security.key.serial.interop=true -Dsun.security.pkcs11.enable-solaris=false SerialDSAPubKey */ import java.io.*; diff --git a/jdk/test/java/security/KeyRep/SerialOld.java b/jdk/test/java/security/KeyRep/SerialOld.java index 3732609872a..fe8eb32d045 100644 --- a/jdk/test/java/security/KeyRep/SerialOld.java +++ b/jdk/test/java/security/KeyRep/SerialOld.java @@ -26,7 +26,7 @@ * @bug 4532506 * @summary Serializing KeyPair on one VM (Sun), * and Deserializing on another (IBM) fails - * @run main/othervm/policy=SerialOld.policy SerialOld + * @run main/othervm/java.security.policy=SerialOld.policy SerialOld */ import java.io.*; diff --git a/jdk/test/java/security/KeyRep/SerialOld.policy b/jdk/test/java/security/KeyRep/SerialOld.policy index b13f3b7399b..e029d09a4e9 100644 --- a/jdk/test/java/security/KeyRep/SerialOld.policy +++ b/jdk/test/java/security/KeyRep/SerialOld.policy @@ -1,55 +1,3 @@ -grant codeBase "file:${java.home}/lib/ext/ucrypto.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; - permission java.lang.RuntimePermission "loadLibrary.j2ucrypto"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.OracleUcrypto"; - permission java.security.SecurityPermission "clearProviderProperties.OracleUcrypto"; - permission java.security.SecurityPermission "removeProviderProperty.OracleUcrypto"; - permission java.io.FilePermission "${java.home}/lib/security/ucrypto-solaris.cfg", "read"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunec.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "loadLibrary.sunec"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunEC"; - permission java.security.SecurityPermission "clearProviderProperties.SunEC"; - permission java.security.SecurityPermission "removeProviderProperty.SunEC"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunjce_provider.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.misc"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunJCE"; - permission java.security.SecurityPermission "clearProviderProperties.SunJCE"; - permission java.security.SecurityPermission "removeProviderProperty.SunJCE"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunpkcs11.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; - permission java.lang.RuntimePermission "loadLibrary.j2pkcs11"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.*"; - permission java.security.SecurityPermission "clearProviderProperties.*"; - permission java.security.SecurityPermission "removeProviderProperty.*"; - permission java.security.SecurityPermission "getProperty.auth.login.defaultCallbackHandler"; - permission java.security.SecurityPermission "authProvider.*"; - // Needed for reading PKCS11 config file and NSS library check - permission java.io.FilePermission "<>", "read"; -}; - -grant codeBase "file:${java.home}/lib/ext/sunmscapi.jar" { - Permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "loadLibrary.sunmscapi"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunMSCAPI"; - permission java.security.SecurityPermission "clearProviderProperties.SunMSCAPI"; - permission java.security.SecurityPermission "removeProviderProperty.SunMSCAPI"; -}; - grant { permission java.io.FilePermission "${test.src}${file.separator}*", "read"; diff --git a/jdk/test/java/security/Security/removing/RemoveStaticProvider.java b/jdk/test/java/security/Security/removing/RemoveStaticProvider.java index 6a03ec73df8..237de13cf7e 100644 --- a/jdk/test/java/security/Security/removing/RemoveStaticProvider.java +++ b/jdk/test/java/security/Security/removing/RemoveStaticProvider.java @@ -25,7 +25,7 @@ * @test * @bug 4420687 * @summary Make sure that a removed provider won't be acceessable. - * @run main/othervm/policy=RemoveStaticProvider.policy RemoveStaticProvider + * @run main/othervm/java.security.policy=RemoveStaticProvider.policy RemoveStaticProvider */ import java.security.*; import javax.crypto.*; diff --git a/jdk/test/java/security/Security/removing/RemoveStaticProvider.policy b/jdk/test/java/security/Security/removing/RemoveStaticProvider.policy index 061e60a1413..f31e5878040 100644 --- a/jdk/test/java/security/Security/removing/RemoveStaticProvider.policy +++ b/jdk/test/java/security/Security/removing/RemoveStaticProvider.policy @@ -1,13 +1,3 @@ - -grant codeBase "file:${java.home}/lib/ext/sunjce_provider.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.misc"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.SunJCE"; - permission java.security.SecurityPermission "clearProviderProperties.SunJCE"; - permission java.security.SecurityPermission "removeProviderProperty.SunJCE"; -}; - grant { permission java.security.SecurityPermission "removeProvider.SunJCE"; permission java.security.SecurityPermission "insertProvider.SunJCE"; diff --git a/jdk/test/jdk/nio/zipfs/Basic.java b/jdk/test/jdk/nio/zipfs/Basic.java index e533b2f82d9..36769729da3 100644 --- a/jdk/test/jdk/nio/zipfs/Basic.java +++ b/jdk/test/jdk/nio/zipfs/Basic.java @@ -35,7 +35,7 @@ import java.io.IOException; * @summary Basic test for zip provider * * @run main Basic - * @run main/othervm/policy=test.policy Basic + * @run main/othervm/java.security.policy=test.policy Basic */ public class Basic { diff --git a/jdk/test/jdk/nio/zipfs/PathOps.java b/jdk/test/jdk/nio/zipfs/PathOps.java index 20e8c5d8fa5..820c04f2f74 100644 --- a/jdk/test/jdk/nio/zipfs/PathOps.java +++ b/jdk/test/jdk/nio/zipfs/PathOps.java @@ -33,7 +33,7 @@ import java.io.IOException; * @summary Tests path operations for zip provider. * * @run main PathOps - * @run main/othervm/policy=test.policy.readonly PathOps + * @run main/othervm/java.security.policy=test.policy.readonly PathOps */ public class PathOps { diff --git a/jdk/test/jdk/nio/zipfs/ZFSTests.java b/jdk/test/jdk/nio/zipfs/ZFSTests.java index a774a271363..23617a31ab5 100644 --- a/jdk/test/jdk/nio/zipfs/ZFSTests.java +++ b/jdk/test/jdk/nio/zipfs/ZFSTests.java @@ -26,7 +26,7 @@ * @summary ZipFileSystem regression tests * * @run main ZFSTests - * @run main/othervm/policy=test.policy ZFSTests + * @run main/othervm/java.security.policy=test.policy ZFSTests */ diff --git a/jdk/test/jdk/nio/zipfs/ZipFSTester.java b/jdk/test/jdk/nio/zipfs/ZipFSTester.java index 95e68fa0e63..60a80c6c169 100644 --- a/jdk/test/jdk/nio/zipfs/ZipFSTester.java +++ b/jdk/test/jdk/nio/zipfs/ZipFSTester.java @@ -43,7 +43,7 @@ import static java.nio.file.StandardCopyOption.*; * 7157656 8002390 7012868 7012856 8015728 8038500 8040059 * @summary Test Zip filesystem provider * @run main ZipFSTester - * @run main/othervm/policy=test.policy ZipFSTester + * @run main/othervm/java.security.policy=test.policy ZipFSTester */ public class ZipFSTester { diff --git a/jdk/test/jdk/nio/zipfs/test.policy b/jdk/test/jdk/nio/zipfs/test.policy index 8e6ae4b6c73..1e91f1f8dcf 100644 --- a/jdk/test/jdk/nio/zipfs/test.policy +++ b/jdk/test/jdk/nio/zipfs/test.policy @@ -1,9 +1,3 @@ -grant codeBase "file:${java.home}/lib/ext/zipfs.jar" { - permission java.io.FilePermission "<>", "read,write"; - permission java.lang.RuntimePermission "fileSystemProvider"; - permission java.util.PropertyPermission "*", "read"; -}; - grant { permission java.io.FilePermission "<>","read,write,delete"; permission java.util.PropertyPermission "test.jdk","read"; diff --git a/jdk/test/jdk/nio/zipfs/test.policy.readonly b/jdk/test/jdk/nio/zipfs/test.policy.readonly index fbd2f14231b..00a8c6a52fd 100644 --- a/jdk/test/jdk/nio/zipfs/test.policy.readonly +++ b/jdk/test/jdk/nio/zipfs/test.policy.readonly @@ -1,9 +1,3 @@ -grant codeBase "file:${java.home}/lib/ext/zipfs.jar" { - permission java.io.FilePermission "<>", "read,write"; - permission java.lang.RuntimePermission "fileSystemProvider"; - permission java.util.PropertyPermission "*", "read"; -}; - grant { permission java.io.FilePermission "<>","read"; permission java.util.PropertyPermission "test.jdk","read"; diff --git a/jdk/test/sun/security/pkcs11/KeyStore/Basic.policy b/jdk/test/sun/security/pkcs11/KeyStore/Basic.policy index 97bb797f0c0..2175b9549e8 100644 --- a/jdk/test/sun/security/pkcs11/KeyStore/Basic.policy +++ b/jdk/test/sun/security/pkcs11/KeyStore/Basic.policy @@ -1,17 +1,3 @@ -grant codeBase "file:${java.home}/lib/ext/sunpkcs11.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; - permission java.lang.RuntimePermission "loadLibrary.j2pkcs11"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.*"; - permission java.security.SecurityPermission "clearProviderProperties.*"; - permission java.security.SecurityPermission "removeProviderProperty.*"; - permission java.security.SecurityPermission "getProperty.auth.login.defaultCallbackHandler"; - permission java.security.SecurityPermission "authProvider.*"; - // Needed for reading PKCS11 config file and NSS library check - permission java.io.FilePermission "<>", "read"; -}; - grant codebase "file:${user.dir}${/}loader.jar" { permission java.security.AllPermission; }; diff --git a/jdk/test/sun/security/pkcs11/Provider/Login.policy b/jdk/test/sun/security/pkcs11/Provider/Login.policy index 424c87431e6..7fee2f88e03 100644 --- a/jdk/test/sun/security/pkcs11/Provider/Login.policy +++ b/jdk/test/sun/security/pkcs11/Provider/Login.policy @@ -1,18 +1,3 @@ -grant codeBase "file:${java.home}/lib/ext/sunpkcs11.jar" { - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; - permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; - permission java.lang.RuntimePermission "loadLibrary.j2pkcs11"; - permission java.util.PropertyPermission "*", "read"; - permission java.security.SecurityPermission "putProviderProperty.*"; - permission java.security.SecurityPermission "clearProviderProperties.*"; - permission java.security.SecurityPermission "removeProviderProperty.*"; - permission java.security.SecurityPermission "getProperty.auth.login.defaultCallbackHandler"; - - permission java.security.SecurityPermission "authProvider.*"; - // Needed for reading PKCS11 config file and NSS library check - permission java.io.FilePermission "<>", "read"; -}; - grant { permission java.util.PropertyPermission "*", "read, write"; permission java.lang.RuntimePermission "loadLibrary.*"; @@ -23,6 +8,5 @@ grant { permission java.io.FilePermission "<>", "read"; permission java.security.SecurityPermission "setProperty.auth.login.defaultCallbackHandler"; - permission java.security.SecurityPermission "authProvider.SunPKCS11-NSS" -; + permission java.security.SecurityPermission "authProvider.SunPKCS11-NSS"; }; From 41a7cfd22f40a429da387a778ad8b2db93c47c38 Mon Sep 17 00:00:00 2001 From: Stuart Marks Date: Mon, 27 Oct 2014 18:30:21 -0700 Subject: [PATCH 33/67] 8062233: add java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java to problem list Reviewed-by: darcy --- jdk/test/ProblemList.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 4ad08ff08bd..1d824bea96b 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -200,6 +200,9 @@ java/nio/file/WatchService/LotsOfEvents.java solaris-all # jdk_rmi +# 7140992 +java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java generic-all + # 7146541 java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java linux-all From 5e152d5fcbcb637c37f2f59b1aace0adff10d78c Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 27 Oct 2014 16:24:43 -0700 Subject: [PATCH 34/67] 8062185: Unpaired braces in javadoc Reviewed-by: psandoz --- jdk/src/java.base/share/classes/java/util/Collection.java | 2 +- .../javax/management/loading/DefaultLoaderRepository.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/util/Collection.java b/jdk/src/java.base/share/classes/java/util/Collection.java index 2ae88727a06..4545faa6143 100644 --- a/jdk/src/java.base/share/classes/java/util/Collection.java +++ b/jdk/src/java.base/share/classes/java/util/Collection.java @@ -518,7 +518,7 @@ public interface Collection extends Iterable { *

The default implementation should be overridden by subclasses that * can return a more efficient spliterator. In order to * preserve expected laziness behavior for the {@link #stream()} and - * {@link #parallelStream()}} methods, spliterators should either have the + * {@link #parallelStream()} methods, spliterators should either have the * characteristic of {@code IMMUTABLE} or {@code CONCURRENT}, or be * late-binding. * If none of these is practical, the overriding class should describe the diff --git a/jdk/src/java.management/share/classes/javax/management/loading/DefaultLoaderRepository.java b/jdk/src/java.management/share/classes/javax/management/loading/DefaultLoaderRepository.java index 8929ec62f36..5cf3ad143b2 100644 --- a/jdk/src/java.management/share/classes/javax/management/loading/DefaultLoaderRepository.java +++ b/jdk/src/java.management/share/classes/javax/management/loading/DefaultLoaderRepository.java @@ -47,7 +47,7 @@ import javax.management.MBeanServerFactory; * DefaultLoaderRepository be rewritten.

* * @deprecated Use - * {@link javax.management.MBeanServer#getClassLoaderRepository()}} + * {@link javax.management.MBeanServer#getClassLoaderRepository()} * instead. * * @since 1.5 From 719facf80bd1314c1025288aac1134b7abd7986a Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Tue, 28 Oct 2014 09:47:32 +0100 Subject: [PATCH 35/67] 8062159: Fix Xrender check to work with sysroot Reviewed-by: tbell, prr --- common/autoconf/generated-configure.sh | 40 +++++++++++++++++--------- common/autoconf/libraries.m4 | 23 +++++++-------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 90d73ace6bc..aae85eec44d 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -4328,7 +4328,7 @@ TOOLCHAIN_DESCRIPTION_xlc="IBM XL C/C++" #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1413533532 +DATE_WHEN_GENERATED=1414485998 ############################################################################### # @@ -44037,17 +44037,6 @@ fi -R$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR" fi - # - # Weird Sol10 something check...TODO change to try compile - # - if test "x${OPENJDK_TARGET_OS}" = xsolaris; then - if test "`uname -r`" = "5.10"; then - if test "`${EGREP} -c XLinearGradient ${OPENWIN_HOME}/share/include/X11/extensions/Xrender.h`" = "0"; then - X_CFLAGS="${X_CFLAGS} -DSOLARIS10_NO_XRENDER_STRUCTS" - fi - fi - fi - ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -44055,7 +44044,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu OLD_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $X_CFLAGS" + CFLAGS="$CFLAGS $SYSROOT_CFLAGS $X_CFLAGS" # Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10 for ac_header in X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h @@ -44079,6 +44068,31 @@ fi done + # If XLinearGradient isn't available in Xrender.h, signal that it needs to be + # defined in libawt_xawt. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if XlinearGradient is defined in Xrender.h" >&5 +$as_echo_n "checking if XlinearGradient is defined in Xrender.h... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +XLinearGradient x; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + X_CFLAGS="$X_CFLAGS -DSOLARIS10_NO_XRENDER_STRUCTS" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$OLD_CFLAGS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' diff --git a/common/autoconf/libraries.m4 b/common/autoconf/libraries.m4 index 5f9eabf250b..36725192d21 100644 --- a/common/autoconf/libraries.m4 +++ b/common/autoconf/libraries.m4 @@ -139,20 +139,9 @@ AC_DEFUN_ONCE([LIB_SETUP_X11], -R$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR" fi - # - # Weird Sol10 something check...TODO change to try compile - # - if test "x${OPENJDK_TARGET_OS}" = xsolaris; then - if test "`uname -r`" = "5.10"; then - if test "`${EGREP} -c XLinearGradient ${OPENWIN_HOME}/share/include/X11/extensions/Xrender.h`" = "0"; then - X_CFLAGS="${X_CFLAGS} -DSOLARIS10_NO_XRENDER_STRUCTS" - fi - fi - fi - AC_LANG_PUSH(C) OLD_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $X_CFLAGS" + CFLAGS="$CFLAGS $SYSROOT_CFLAGS $X_CFLAGS" # Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10 AC_CHECK_HEADERS([X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h], @@ -164,6 +153,16 @@ AC_DEFUN_ONCE([LIB_SETUP_X11], ] ) + # If XLinearGradient isn't available in Xrender.h, signal that it needs to be + # defined in libawt_xawt. + AC_MSG_CHECKING([if XlinearGradient is defined in Xrender.h]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include ]], + [[XLinearGradient x;]])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + X_CFLAGS="$X_CFLAGS -DSOLARIS10_NO_XRENDER_STRUCTS"]) + CFLAGS="$OLD_CFLAGS" AC_LANG_POP(C) From b051027d6f13c3c2a03bbf64039374f9142c9667 Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Tue, 28 Oct 2014 15:36:27 +0300 Subject: [PATCH 36/67] 8023173: FileDescriptor should respect append flag Reviewed-by: martin, alanb, rriggs --- jdk/make/mapfiles/libjava/mapfile-vers | 1 + .../java.base/share/classes/java/io/File.java | 2 +- .../classes/java/io/FileOutputStream.java | 23 ++++---- .../classes/java/nio/file/FileStore.java | 2 +- .../java/nio/file/attribute/package-info.java | 2 +- .../sun/misc/JavaIOFileDescriptorAccess.java | 2 + .../classes/sun/nio/ch/FileChannelImpl.java | 29 +++++----- .../java.base/share/native/libjava/io_util.h | 1 + .../unix/classes/java/io/FileDescriptor.java | 23 +++++++- .../sun/nio/ch/FileDispatcherImpl.java | 4 -- .../sun/nio/fs/UnixChannelFactory.java | 3 +- .../unix/native/libjava/FileDescriptor_md.c | 13 +++++ .../unix/native/libjava/io_util_md.c | 8 +++ .../classes/java/io/FileDescriptor.java | 13 +++++ .../sun/nio/ch/FileDispatcherImpl.java | 20 ++----- .../sun/nio/fs/WindowsChannelFactory.java | 3 +- .../native/libjava/FileDescriptor_md.c | 4 ++ .../windows/native/libjava/io_util_md.c | 8 +++ .../io/FileDescriptor/RememberAppend.java | 54 +++++++++++++++++++ 19 files changed, 162 insertions(+), 53 deletions(-) create mode 100644 jdk/test/java/io/FileDescriptor/RememberAppend.java diff --git a/jdk/make/mapfiles/libjava/mapfile-vers b/jdk/make/mapfiles/libjava/mapfile-vers index b14ae84c1a9..08466af08f3 100644 --- a/jdk/make/mapfiles/libjava/mapfile-vers +++ b/jdk/make/mapfiles/libjava/mapfile-vers @@ -75,6 +75,7 @@ SUNWprivate_1.1 { Java_java_io_FileDescriptor_initIDs; Java_java_io_FileDescriptor_sync; + Java_java_io_FileDescriptor_getAppend; Java_java_io_FileInputStream_available; Java_java_io_FileInputStream_close0; Java_java_io_FileInputStream_initIDs; diff --git a/jdk/src/java.base/share/classes/java/io/File.java b/jdk/src/java.base/share/classes/java/io/File.java index 306cc84097d..5aa6b200163 100644 --- a/jdk/src/java.base/share/classes/java/io/File.java +++ b/jdk/src/java.base/share/classes/java/io/File.java @@ -1588,7 +1588,7 @@ public class File /** * A convenience method to set the owner's read permission for this abstract * pathname. On some platforms it may be possible to start the Java virtual - * machine with special privileges that allow it to read files that that are + * machine with special privileges that allow it to read files that are * marked as unreadable. * *

An invocation of this method of the form file.setReadable(arg) diff --git a/jdk/src/java.base/share/classes/java/io/FileOutputStream.java b/jdk/src/java.base/share/classes/java/io/FileOutputStream.java index 281a695e6df..43a7d053bbb 100644 --- a/jdk/src/java.base/share/classes/java/io/FileOutputStream.java +++ b/jdk/src/java.base/share/classes/java/io/FileOutputStream.java @@ -26,6 +26,8 @@ package java.io; import java.nio.channels.FileChannel; +import sun.misc.SharedSecrets; +import sun.misc.JavaIOFileDescriptorAccess; import sun.nio.ch.FileChannelImpl; @@ -52,16 +54,17 @@ import sun.nio.ch.FileChannelImpl; public class FileOutputStream extends OutputStream { + /** + * Access to FileDescriptor internals. + */ + private static final JavaIOFileDescriptorAccess fdAccess = + SharedSecrets.getJavaIOFileDescriptorAccess(); + /** * The system dependent file descriptor. */ private final FileDescriptor fd; - /** - * True if the file is opened for append. - */ - private final boolean append; - /** * The associated channel, initialized lazily. */ @@ -207,7 +210,6 @@ class FileOutputStream extends OutputStream } this.fd = new FileDescriptor(); fd.attach(this); - this.append = append; this.path = name; open(name, append); @@ -245,7 +247,6 @@ class FileOutputStream extends OutputStream security.checkWrite(fdObj); } this.fd = fdObj; - this.append = false; this.path = null; fd.attach(this); @@ -287,7 +288,7 @@ class FileOutputStream extends OutputStream * @exception IOException if an I/O error occurs. */ public void write(int b) throws IOException { - write(b, append); + write(b, fdAccess.getAppend(fd)); } /** @@ -310,7 +311,7 @@ class FileOutputStream extends OutputStream * @exception IOException if an I/O error occurs. */ public void write(byte b[]) throws IOException { - writeBytes(b, 0, b.length, append); + writeBytes(b, 0, b.length, fdAccess.getAppend(fd)); } /** @@ -323,7 +324,7 @@ class FileOutputStream extends OutputStream * @exception IOException if an I/O error occurs. */ public void write(byte b[], int off, int len) throws IOException { - writeBytes(b, off, len, append); + writeBytes(b, off, len, fdAccess.getAppend(fd)); } /** @@ -395,7 +396,7 @@ class FileOutputStream extends OutputStream public FileChannel getChannel() { synchronized (this) { if (channel == null) { - channel = FileChannelImpl.open(fd, path, false, true, append, this); + channel = FileChannelImpl.open(fd, path, false, true, this); } return channel; } diff --git a/jdk/src/java.base/share/classes/java/nio/file/FileStore.java b/jdk/src/java.base/share/classes/java/nio/file/FileStore.java index 008f6f722c1..ad94cc90040 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/FileStore.java +++ b/jdk/src/java.base/share/classes/java/nio/file/FileStore.java @@ -208,7 +208,7 @@ public abstract class FileStore { * @param attribute * the attribute to read - * @return the attribute value; {@code null} may be a valid for some + * @return the attribute value; {@code null} may be valid for some * attributes * * @throws UnsupportedOperationException diff --git a/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java b/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java index c1bf6b6482b..be46551c60d 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java +++ b/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java @@ -51,7 +51,7 @@ *

An attribute view provides a read-only or updatable view of the non-opaque * values, or metadata, associated with objects in a file system. * The {@link java.nio.file.attribute.FileAttributeView} interface is - * extended by several other interfaces that views to specific sets of file + * extended by several other interfaces that provide views to specific sets of file * attributes. {@code FileAttributeViews} are selected by invoking the {@link * java.nio.file.Files#getFileAttributeView} method with a * type-token to identify the required view. Views can also be identified diff --git a/jdk/src/java.base/share/classes/sun/misc/JavaIOFileDescriptorAccess.java b/jdk/src/java.base/share/classes/sun/misc/JavaIOFileDescriptorAccess.java index 9e987e6c371..478c4a8c8cc 100644 --- a/jdk/src/java.base/share/classes/sun/misc/JavaIOFileDescriptorAccess.java +++ b/jdk/src/java.base/share/classes/sun/misc/JavaIOFileDescriptorAccess.java @@ -33,6 +33,8 @@ import java.io.FileDescriptor; public interface JavaIOFileDescriptorAccess { public void set(FileDescriptor obj, int fd); public int get(FileDescriptor fd); + public void setAppend(FileDescriptor obj, boolean append); + public boolean getAppend(FileDescriptor obj); // Only valid on Windows public void setHandle(FileDescriptor obj, long handle); diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java index bb127e8a5f2..2c3102feadd 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java @@ -44,6 +44,8 @@ import java.util.ArrayList; import java.util.List; import sun.misc.Cleaner; +import sun.misc.JavaIOFileDescriptorAccess; +import sun.misc.SharedSecrets; import sun.security.action.GetPropertyAction; public class FileChannelImpl @@ -52,6 +54,10 @@ public class FileChannelImpl // Memory allocation size for mapping buffers private static final long allocationGranularity; + // Access to FileDispatcher internals + private static final JavaIOFileDescriptorAccess fdAccess = + SharedSecrets.getJavaIOFileDescriptorAccess(); + // Used to make native read and write calls private final FileDispatcher nd; @@ -61,7 +67,6 @@ public class FileChannelImpl // File access mode (immutable) private final boolean writable; private final boolean readable; - private final boolean append; // Required to prevent finalization of creating stream (immutable) private final Object parent; @@ -77,31 +82,23 @@ public class FileChannelImpl private final Object positionLock = new Object(); private FileChannelImpl(FileDescriptor fd, String path, boolean readable, - boolean writable, boolean append, Object parent) + boolean writable, Object parent) { this.fd = fd; this.readable = readable; this.writable = writable; - this.append = append; this.parent = parent; this.path = path; - this.nd = new FileDispatcherImpl(append); + this.nd = new FileDispatcherImpl(); } - // Used by FileInputStream.getChannel() and RandomAccessFile.getChannel() + // Used by FileInputStream.getChannel(), FileOutputStream.getChannel + // and RandomAccessFile.getChannel() public static FileChannel open(FileDescriptor fd, String path, boolean readable, boolean writable, Object parent) { - return new FileChannelImpl(fd, path, readable, writable, false, parent); - } - - // Used by FileOutputStream.getChannel - public static FileChannel open(FileDescriptor fd, String path, - boolean readable, boolean writable, - boolean append, Object parent) - { - return new FileChannelImpl(fd, path, readable, writable, append, parent); + return new FileChannelImpl(fd, path, readable, writable, parent); } private void ensureOpen() throws IOException { @@ -109,7 +106,6 @@ public class FileChannelImpl throw new ClosedChannelException(); } - // -- Standard channel operations -- protected void implCloseChannel() throws IOException { @@ -258,6 +254,7 @@ public class FileChannelImpl ti = threads.add(); if (!isOpen()) return 0; + boolean append = fdAccess.getAppend(fd); do { // in append-mode then position is advanced to end before writing p = (append) ? nd.size(fd) : position0(fd, -1); @@ -284,7 +281,7 @@ public class FileChannelImpl if (!isOpen()) return null; do { - p = position0(fd, newPosition); + p = position0(fd, newPosition); } while ((p == IOStatus.INTERRUPTED) && isOpen()); return this; } finally { diff --git a/jdk/src/java.base/share/native/libjava/io_util.h b/jdk/src/java.base/share/native/libjava/io_util.h index 120594fe804..1d7920512ba 100644 --- a/jdk/src/java.base/share/native/libjava/io_util.h +++ b/jdk/src/java.base/share/native/libjava/io_util.h @@ -28,6 +28,7 @@ extern jfieldID IO_fd_fdID; extern jfieldID IO_handle_fdID; +extern jfieldID IO_append_fdID; #ifdef _ALLBSD_SOURCE #include diff --git a/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java b/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java index 4017b3a2a9a..35518e4493d 100644 --- a/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java +++ b/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java @@ -51,16 +51,22 @@ public final class FileDescriptor { private List otherParents; private boolean closed; + /** + * true, if file is opened for appending. + */ + private boolean append; + /** * Constructs an (invalid) FileDescriptor * object. */ - public /**/ FileDescriptor() { + public FileDescriptor() { fd = -1; } - private /* */ FileDescriptor(int fd) { + private FileDescriptor(int fd) { this.fd = fd; + this.append = getAppend(fd); } /** @@ -149,6 +155,14 @@ public final class FileDescriptor { return obj.fd; } + public void setAppend(FileDescriptor obj, boolean append) { + obj.append = append; + } + + public boolean getAppend(FileDescriptor obj) { + return obj.append; + } + public void setHandle(FileDescriptor obj, long handle) { throw new UnsupportedOperationException(); } @@ -160,6 +174,11 @@ public final class FileDescriptor { ); } + /** + * Returns true, if the file was opened for appending. + */ + private static native boolean getAppend(int fd); + /* * Package private methods to track referents. * If multiple streams point to the same FileDescriptor, we cycle diff --git a/jdk/src/java.base/unix/classes/sun/nio/ch/FileDispatcherImpl.java b/jdk/src/java.base/unix/classes/sun/nio/ch/FileDispatcherImpl.java index 2c7504caa4a..c6c85f7fac9 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/ch/FileDispatcherImpl.java +++ b/jdk/src/java.base/unix/classes/sun/nio/ch/FileDispatcherImpl.java @@ -35,10 +35,6 @@ class FileDispatcherImpl extends FileDispatcher init(); } - FileDispatcherImpl(boolean append) { - /* append is ignored */ - } - FileDispatcherImpl() { } diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java index c6f074e5941..bc194f960ae 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java @@ -134,7 +134,7 @@ class UnixChannelFactory { throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed"); FileDescriptor fdObj = open(dfd, path, pathForPermissionCheck, flags, mode); - return FileChannelImpl.open(fdObj, path.toString(), flags.read, flags.write, flags.append, null); + return FileChannelImpl.open(fdObj, path.toString(), flags.read, flags.write, null); } /** @@ -288,6 +288,7 @@ class UnixChannelFactory { // create java.io.FileDescriptor FileDescriptor fdObj = new FileDescriptor(); fdAccess.set(fdObj, fd); + fdAccess.setAppend(fdObj, flags.append); return fdObj; } } diff --git a/jdk/src/java.base/unix/native/libjava/FileDescriptor_md.c b/jdk/src/java.base/unix/native/libjava/FileDescriptor_md.c index 7147a14c544..11b96bb6f90 100644 --- a/jdk/src/java.base/unix/native/libjava/FileDescriptor_md.c +++ b/jdk/src/java.base/unix/native/libjava/FileDescriptor_md.c @@ -23,6 +23,9 @@ * questions. */ +#include +#include + #include "jvm.h" #include "io_util_md.h" @@ -35,6 +38,9 @@ /* field id for jint 'fd' in java.io.FileDescriptor */ jfieldID IO_fd_fdID; +/* field id for jboolean 'append' in java.io.FileDescriptor */ +jfieldID IO_append_fdID; + /************************************************************** * static methods to store field ID's in initializers */ @@ -42,6 +48,7 @@ jfieldID IO_fd_fdID; JNIEXPORT void JNICALL Java_java_io_FileDescriptor_initIDs(JNIEnv *env, jclass fdClass) { IO_fd_fdID = (*env)->GetFieldID(env, fdClass, "fd", "I"); + IO_append_fdID = (*env)->GetFieldID(env, fdClass, "append", "Z"); } /************************************************************** @@ -55,3 +62,9 @@ Java_java_io_FileDescriptor_sync(JNIEnv *env, jobject this) { JNU_ThrowByName(env, "java/io/SyncFailedException", "sync failed"); } } + +JNIEXPORT jboolean JNICALL +Java_java_io_FileDescriptor_getAppend(JNIEnv *env, jclass fdClass, jint fd) { + int flags = fcntl(fd, F_GETFL); + return ((flags & O_APPEND) == 0) ? JNI_FALSE : JNI_TRUE; +} diff --git a/jdk/src/java.base/unix/native/libjava/io_util_md.c b/jdk/src/java.base/unix/native/libjava/io_util_md.c index 4c539ecdafb..ff7b9b83d46 100644 --- a/jdk/src/java.base/unix/native/libjava/io_util_md.c +++ b/jdk/src/java.base/unix/native/libjava/io_util_md.c @@ -107,7 +107,15 @@ fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) #endif fd = handleOpen(ps, flags, 0666); if (fd != -1) { + jobject fdobj; + jboolean append; SET_FD(this, fd, fid); + + fdobj = (*env)->GetObjectField(env, this, fid); + if (fdobj != NULL) { + append = (flags & O_APPEND) == 0 ? JNI_FALSE : JNI_TRUE; + (*env)->SetBooleanField(env, fdobj, IO_append_fdID, append); + } } else { throwFileNotFoundException(env, path); } diff --git a/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java b/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java index c8cbc218df3..0ce43ef1c9d 100644 --- a/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java +++ b/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java @@ -50,6 +50,11 @@ public final class FileDescriptor { private List otherParents; private boolean closed; + /** + * true, if file is opened for appending. + */ + private boolean append; + /** * Constructs an (invalid) FileDescriptor * object. @@ -75,6 +80,14 @@ public final class FileDescriptor { return obj.fd; } + public void setAppend(FileDescriptor obj, boolean append) { + obj.append = append; + } + + public boolean getAppend(FileDescriptor obj) { + return obj.append; + } + public void setHandle(FileDescriptor obj, long handle) { obj.handle = handle; } diff --git a/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java b/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java index ccab64d12a4..19997d0c1ec 100644 --- a/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java +++ b/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java @@ -31,22 +31,14 @@ import sun.misc.JavaIOFileDescriptorAccess; class FileDispatcherImpl extends FileDispatcher { + private static final JavaIOFileDescriptorAccess fdAccess = + SharedSecrets.getJavaIOFileDescriptorAccess(); + static { IOUtil.load(); } - /** - * Indicates if the dispatcher should first advance the file position - * to the end of file when writing. - */ - private final boolean append; - - FileDispatcherImpl(boolean append) { - this.append = append; - } - FileDispatcherImpl() { - this(false); } @Override @@ -71,7 +63,7 @@ class FileDispatcherImpl extends FileDispatcher } int write(FileDescriptor fd, long address, int len) throws IOException { - return write0(fd, address, len, append); + return write0(fd, address, len, fdAccess.getAppend(fd)); } int pwrite(FileDescriptor fd, long address, int len, long position) @@ -81,7 +73,7 @@ class FileDispatcherImpl extends FileDispatcher } long writev(FileDescriptor fd, long address, int len) throws IOException { - return writev0(fd, address, len, append); + return writev0(fd, address, len, fdAccess.getAppend(fd)); } int force(FileDescriptor fd, boolean metaData) throws IOException { @@ -112,8 +104,6 @@ class FileDispatcherImpl extends FileDispatcher FileDescriptor duplicateForMapping(FileDescriptor fd) throws IOException { // on Windows we need to keep a handle to the file - JavaIOFileDescriptorAccess fdAccess = - SharedSecrets.getJavaIOFileDescriptorAccess(); FileDescriptor result = new FileDescriptor(); long handle = duplicateHandle(fdAccess.getHandle(fd)); fdAccess.setHandle(result, handle); diff --git a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java index 46d063ca172..de8cc8d7f5c 100644 --- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java +++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java @@ -160,7 +160,7 @@ class WindowsChannelFactory { throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed"); FileDescriptor fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor); - return FileChannelImpl.open(fdObj, pathForWindows, flags.read, flags.write, flags.append, null); + return FileChannelImpl.open(fdObj, pathForWindows, flags.read, flags.write, null); } /** @@ -339,6 +339,7 @@ class WindowsChannelFactory { // create FileDescriptor and return FileDescriptor fdObj = new FileDescriptor(); fdAccess.setHandle(fdObj, handle); + fdAccess.setAppend(fdObj, flags.append); return fdObj; } } diff --git a/jdk/src/java.base/windows/native/libjava/FileDescriptor_md.c b/jdk/src/java.base/windows/native/libjava/FileDescriptor_md.c index db04cd47653..7921a9b1d2f 100644 --- a/jdk/src/java.base/windows/native/libjava/FileDescriptor_md.c +++ b/jdk/src/java.base/windows/native/libjava/FileDescriptor_md.c @@ -42,6 +42,9 @@ jfieldID IO_fd_fdID; /* field id for jlong 'handle' in java.io.FileDescriptor */ jfieldID IO_handle_fdID; +/* field id for jboolean 'append' in java.io.FileDescriptor */ +jfieldID IO_append_fdID; + /************************************************************** * static methods to store field IDs in initializers */ @@ -50,6 +53,7 @@ JNIEXPORT void JNICALL Java_java_io_FileDescriptor_initIDs(JNIEnv *env, jclass fdClass) { CHECK_NULL(IO_fd_fdID = (*env)->GetFieldID(env, fdClass, "fd", "I")); CHECK_NULL(IO_handle_fdID = (*env)->GetFieldID(env, fdClass, "handle", "J")); + CHECK_NULL(IO_append_fdID = (*env)->GetFieldID(env, fdClass, "append", "Z")); } JNIEXPORT jlong JNICALL diff --git a/jdk/src/java.base/windows/native/libjava/io_util_md.c b/jdk/src/java.base/windows/native/libjava/io_util_md.c index ba2db4de401..a37ecb6e28b 100644 --- a/jdk/src/java.base/windows/native/libjava/io_util_md.c +++ b/jdk/src/java.base/windows/native/libjava/io_util_md.c @@ -275,7 +275,15 @@ fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) { FD h = winFileHandleOpen(env, path, flags); if (h >= 0) { + jobject fdobj; + jboolean append; SET_FD(this, h, fid); + + fdobj = (*env)->GetObjectField(env, this, fid); + if (fdobj != NULL) { + append = (flags & O_APPEND) == 0 ? JNI_FALSE : JNI_TRUE; + (*env)->SetBooleanField(env, fdobj, IO_append_fdID, append); + } } } diff --git a/jdk/test/java/io/FileDescriptor/RememberAppend.java b/jdk/test/java/io/FileDescriptor/RememberAppend.java new file mode 100644 index 00000000000..cc08f66924c --- /dev/null +++ b/jdk/test/java/io/FileDescriptor/RememberAppend.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, 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 8023173 + * @summary FileDescriptor should respect append flag + */ + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileOutputStream; + +public class RememberAppend { + private static final byte[] bytes = "ABC ".getBytes(); + + public static void main(String[] args) throws Throwable { + File f = File.createTempFile("tmp.file", null); + f.deleteOnExit(); + + try (FileOutputStream fos1 = new FileOutputStream(f.getPath(), true)) { + fos1.write(bytes); + } + + try (FileOutputStream fos1 = new FileOutputStream(f.getPath(), true); + FileOutputStream fos2 = new FileOutputStream(fos1.getFD())) { + fos2.write(bytes); + } + + if (f.length() != 2 * bytes.length) { + throw new RuntimeException("Append flag ignored"); + } + } +} From 178193aa935fdbaa227a70af43dce64f5762afaf Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Tue, 28 Oct 2014 19:55:20 -0400 Subject: [PATCH 37/67] 8062288: Minor re-org of java/sql testing tests Reviewed-by: joehw, rriggs --- jdk/test/java/sql/{ => testng}/TEST.properties | 0 .../sql/{ => testng}/test/sql/BatchUpdateExceptionTests.java | 0 .../java/sql/{ => testng}/test/sql/DataTruncationTests.java | 0 jdk/test/java/sql/{ => testng}/test/sql/DateTests.java | 0 .../{ => testng}/test/sql/DriverManagerPermissionsTests.java | 0 jdk/test/java/sql/{ => testng}/test/sql/DriverManagerTests.java | 0 .../sql/{ => testng}/test/sql/SQLClientInfoExceptionTests.java | 0 .../java/sql/{ => testng}/test/sql/SQLDataExceptionTests.java | 0 jdk/test/java/sql/{ => testng}/test/sql/SQLExceptionTests.java | 0 .../test/sql/SQLFeatureNotSupportedExceptionTests.java | 0 .../test/sql/SQLIntegrityConstraintViolationExceptionTests.java | 0 .../test/sql/SQLInvalidAuthorizationSpecExceptionTests.java | 0 .../test/sql/SQLNonTransientConnectionExceptionTests.java | 0 .../{ => testng}/test/sql/SQLNonTransientExceptionTests.java | 0 .../sql/{ => testng}/test/sql/SQLRecoverableExceptionTests.java | 0 .../sql/{ => testng}/test/sql/SQLSyntaxErrorExceptionTests.java | 0 .../sql/{ => testng}/test/sql/SQLTimeoutExceptionTests.java | 0 .../test/sql/SQLTransactionRollbackExceptionTests.java | 0 .../test/sql/SQLTransientConnectionExceptionTests.java | 0 .../sql/{ => testng}/test/sql/SQLTransientExceptionTests.java | 0 jdk/test/java/sql/{ => testng}/test/sql/SQLWarningTests.java | 0 jdk/test/java/sql/{ => testng}/test/sql/TimeTests.java | 0 jdk/test/java/sql/{ => testng}/test/sql/TimestampTests.java | 0 jdk/test/java/sql/{ => testng}/util/BaseTest.java | 0 jdk/test/java/sql/{ => testng}/util/DriverActionImpl.java | 0 .../sql/{ => testng}/util/SerializedBatchUpdateException.java | 0 jdk/test/java/sql/{ => testng}/util/StubConnection.java | 0 jdk/test/java/sql/{ => testng}/util/StubDriver.java | 0 jdk/test/java/sql/{ => testng}/util/StubDriverDA.java | 0 jdk/test/java/sql/{ => testng}/util/TestPolicy.java | 0 jdk/test/javax/sql/testng/TEST.properties | 2 +- 31 files changed, 1 insertion(+), 1 deletion(-) rename jdk/test/java/sql/{ => testng}/TEST.properties (100%) rename jdk/test/java/sql/{ => testng}/test/sql/BatchUpdateExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/DataTruncationTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/DateTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/DriverManagerPermissionsTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/DriverManagerTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLClientInfoExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLDataExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLFeatureNotSupportedExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLIntegrityConstraintViolationExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLNonTransientConnectionExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLNonTransientExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLRecoverableExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLSyntaxErrorExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLTimeoutExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLTransactionRollbackExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLTransientConnectionExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLTransientExceptionTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/SQLWarningTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/TimeTests.java (100%) rename jdk/test/java/sql/{ => testng}/test/sql/TimestampTests.java (100%) rename jdk/test/java/sql/{ => testng}/util/BaseTest.java (100%) rename jdk/test/java/sql/{ => testng}/util/DriverActionImpl.java (100%) rename jdk/test/java/sql/{ => testng}/util/SerializedBatchUpdateException.java (100%) rename jdk/test/java/sql/{ => testng}/util/StubConnection.java (100%) rename jdk/test/java/sql/{ => testng}/util/StubDriver.java (100%) rename jdk/test/java/sql/{ => testng}/util/StubDriverDA.java (100%) rename jdk/test/java/sql/{ => testng}/util/TestPolicy.java (100%) diff --git a/jdk/test/java/sql/TEST.properties b/jdk/test/java/sql/testng/TEST.properties similarity index 100% rename from jdk/test/java/sql/TEST.properties rename to jdk/test/java/sql/testng/TEST.properties diff --git a/jdk/test/java/sql/test/sql/BatchUpdateExceptionTests.java b/jdk/test/java/sql/testng/test/sql/BatchUpdateExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/BatchUpdateExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/BatchUpdateExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/DataTruncationTests.java b/jdk/test/java/sql/testng/test/sql/DataTruncationTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/DataTruncationTests.java rename to jdk/test/java/sql/testng/test/sql/DataTruncationTests.java diff --git a/jdk/test/java/sql/test/sql/DateTests.java b/jdk/test/java/sql/testng/test/sql/DateTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/DateTests.java rename to jdk/test/java/sql/testng/test/sql/DateTests.java diff --git a/jdk/test/java/sql/test/sql/DriverManagerPermissionsTests.java b/jdk/test/java/sql/testng/test/sql/DriverManagerPermissionsTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/DriverManagerPermissionsTests.java rename to jdk/test/java/sql/testng/test/sql/DriverManagerPermissionsTests.java diff --git a/jdk/test/java/sql/test/sql/DriverManagerTests.java b/jdk/test/java/sql/testng/test/sql/DriverManagerTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/DriverManagerTests.java rename to jdk/test/java/sql/testng/test/sql/DriverManagerTests.java diff --git a/jdk/test/java/sql/test/sql/SQLClientInfoExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLClientInfoExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLClientInfoExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLClientInfoExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLDataExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLDataExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLDataExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLDataExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLFeatureNotSupportedExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLFeatureNotSupportedExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLFeatureNotSupportedExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLFeatureNotSupportedExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLIntegrityConstraintViolationExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLIntegrityConstraintViolationExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLIntegrityConstraintViolationExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLIntegrityConstraintViolationExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLNonTransientConnectionExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLNonTransientConnectionExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLNonTransientConnectionExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLNonTransientConnectionExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLNonTransientExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLNonTransientExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLNonTransientExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLNonTransientExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLRecoverableExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLRecoverableExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLRecoverableExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLRecoverableExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLSyntaxErrorExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLSyntaxErrorExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLSyntaxErrorExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLSyntaxErrorExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLTimeoutExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLTimeoutExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLTimeoutExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLTimeoutExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLTransactionRollbackExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLTransactionRollbackExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLTransactionRollbackExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLTransactionRollbackExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLTransientConnectionExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLTransientConnectionExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLTransientConnectionExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLTransientConnectionExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLTransientExceptionTests.java b/jdk/test/java/sql/testng/test/sql/SQLTransientExceptionTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLTransientExceptionTests.java rename to jdk/test/java/sql/testng/test/sql/SQLTransientExceptionTests.java diff --git a/jdk/test/java/sql/test/sql/SQLWarningTests.java b/jdk/test/java/sql/testng/test/sql/SQLWarningTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/SQLWarningTests.java rename to jdk/test/java/sql/testng/test/sql/SQLWarningTests.java diff --git a/jdk/test/java/sql/test/sql/TimeTests.java b/jdk/test/java/sql/testng/test/sql/TimeTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/TimeTests.java rename to jdk/test/java/sql/testng/test/sql/TimeTests.java diff --git a/jdk/test/java/sql/test/sql/TimestampTests.java b/jdk/test/java/sql/testng/test/sql/TimestampTests.java similarity index 100% rename from jdk/test/java/sql/test/sql/TimestampTests.java rename to jdk/test/java/sql/testng/test/sql/TimestampTests.java diff --git a/jdk/test/java/sql/util/BaseTest.java b/jdk/test/java/sql/testng/util/BaseTest.java similarity index 100% rename from jdk/test/java/sql/util/BaseTest.java rename to jdk/test/java/sql/testng/util/BaseTest.java diff --git a/jdk/test/java/sql/util/DriverActionImpl.java b/jdk/test/java/sql/testng/util/DriverActionImpl.java similarity index 100% rename from jdk/test/java/sql/util/DriverActionImpl.java rename to jdk/test/java/sql/testng/util/DriverActionImpl.java diff --git a/jdk/test/java/sql/util/SerializedBatchUpdateException.java b/jdk/test/java/sql/testng/util/SerializedBatchUpdateException.java similarity index 100% rename from jdk/test/java/sql/util/SerializedBatchUpdateException.java rename to jdk/test/java/sql/testng/util/SerializedBatchUpdateException.java diff --git a/jdk/test/java/sql/util/StubConnection.java b/jdk/test/java/sql/testng/util/StubConnection.java similarity index 100% rename from jdk/test/java/sql/util/StubConnection.java rename to jdk/test/java/sql/testng/util/StubConnection.java diff --git a/jdk/test/java/sql/util/StubDriver.java b/jdk/test/java/sql/testng/util/StubDriver.java similarity index 100% rename from jdk/test/java/sql/util/StubDriver.java rename to jdk/test/java/sql/testng/util/StubDriver.java diff --git a/jdk/test/java/sql/util/StubDriverDA.java b/jdk/test/java/sql/testng/util/StubDriverDA.java similarity index 100% rename from jdk/test/java/sql/util/StubDriverDA.java rename to jdk/test/java/sql/testng/util/StubDriverDA.java diff --git a/jdk/test/java/sql/util/TestPolicy.java b/jdk/test/java/sql/testng/util/TestPolicy.java similarity index 100% rename from jdk/test/java/sql/util/TestPolicy.java rename to jdk/test/java/sql/testng/util/TestPolicy.java diff --git a/jdk/test/javax/sql/testng/TEST.properties b/jdk/test/javax/sql/testng/TEST.properties index 6959dd476fd..97bfe7c5e31 100644 --- a/jdk/test/javax/sql/testng/TEST.properties +++ b/jdk/test/javax/sql/testng/TEST.properties @@ -1,4 +1,4 @@ # JDBC unit tests uses TestNG TestNG.dirs= . othervm.dirs= . -lib.dirs = /java/sql/ +lib.dirs = /java/sql/testng From 7abf72a2dc015f5c2bf154c864dfb6bd2e503941 Mon Sep 17 00:00:00 2001 From: Mattias Tobiasson Date: Tue, 28 Oct 2014 11:45:31 +0100 Subject: [PATCH 38/67] 8061960: java/lang/instrument/DaemonThread/TestDaemonThread.java regularly fails due to exceeded timeout Move timeout parameter to correct place on command line Reviewed-by: jbachorik --- .../java/lang/instrument/DaemonThread/TestDaemonThread.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThread.java b/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThread.java index 12246b1a676..5346f73b129 100644 --- a/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThread.java +++ b/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThread.java @@ -28,7 +28,7 @@ * * @build jdk.testlibrary.* DummyAgent DummyClass TestDaemonThreadLauncher TestDaemonThread * @run shell ../MakeJAR3.sh DummyAgent - * @run main TestDaemonThreadLauncher /timeout=240 + * @run main/timeout=240 TestDaemonThreadLauncher * */ import java.io.File; From c92cca11f6b6deee74d1b6e6dd542883689d4aca Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Tue, 28 Oct 2014 17:22:17 +0530 Subject: [PATCH 39/67] 8062216: [nashorn] regresion test failure with TimeZone Reviewed-by: hannesw, lagergren --- nashorn/test/script/basic/JDK-8062024.js | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/test/script/basic/JDK-8062024.js b/nashorn/test/script/basic/JDK-8062024.js index 453dcfad476..92085cac1c0 100644 --- a/nashorn/test/script/basic/JDK-8062024.js +++ b/nashorn/test/script/basic/JDK-8062024.js @@ -25,6 +25,7 @@ * JDK-8062024: Issue with date.setFullYear when time other than midnight * * @test + * @option -timezone=Asia/Calcutta * @run */ From 63080521d711e8ac98411c3a89be3fb557e7c0ea Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Tue, 28 Oct 2014 17:02:08 -0400 Subject: [PATCH 40/67] 8058093: Test nsk/stress/jck60/jck60014: assert in src/share/vm/oops/constantPool.cpp: should not be resolved otherwise 8044209: nsk/split_verifier/security/coglio06 fails with exit code 97 - missing 'prohibited package name' Fix resolution error saving. Reviewed-by: lfoltan, sspitsyn, hseigel, ctornqvi --- hotspot/src/share/vm/oops/constantPool.cpp | 49 ++++++++++++------- hotspot/src/share/vm/oops/constantPool.hpp | 11 ++++- .../src/share/vm/runtime/deoptimization.cpp | 2 +- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index fb474cec05b..d547398dfae 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -206,7 +206,8 @@ void ConstantPool::trace_class_resolution(constantPoolHandle this_cp, KlassHandl } } -Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS) { +Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, + bool save_resolution_error, TRAPS) { assert(THREAD->is_Java_thread(), "must be a Java thread"); // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*. @@ -249,7 +250,18 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS) // Failed to resolve class. We must record the errors so that subsequent attempts // to resolve this constant pool entry fail with the same error (JVMS 5.4.3). if (HAS_PENDING_EXCEPTION) { - save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0); + if (save_resolution_error) { + save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL); + // If CHECK_NULL above doesn't return the exception, that means that + // some other thread has beaten us and has resolved the class. + // To preserve old behavior, we return the resolved class. + entry = this_cp->resolved_klass_at(which); + assert(entry.is_resolved(), "must be resolved if exception was cleared"); + assert(entry.get_klass()->is_klass(), "must be resolved to a klass"); + return entry.get_klass(); + } else { + return NULL; // return the pending exception + } } // Make this class loader depend upon the class loader owning the class reference @@ -260,10 +272,10 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS) // skip resolving the constant pool so that this code gets // called the next time some bytecodes refer to this class. trace_class_resolution(this_cp, k); - return k(); - } else { - this_cp->klass_at_put(which, k()); - } + return k(); + } else { + this_cp->klass_at_put(which, k()); + } entry = this_cp->resolved_klass_at(which); assert(entry.is_resolved() && entry.get_klass()->is_klass(), "must be resolved at this point"); @@ -573,24 +585,25 @@ void ConstantPool::save_and_throw_exception(constantPoolHandle this_cp, int whic Symbol* message = exception_message(this_cp, which, tag, PENDING_EXCEPTION); SystemDictionary::add_resolution_error(this_cp, which, error, message); // CAS in the tag. If a thread beat us to registering this error that's fine. - // If another thread resolved the reference, this is an error. The resolution - // must deterministically get an error. So why do we save this? - // We save this because jvmti can add classes to the bootclass path after this - // error, so it needs to get the same error if the error is first. + // If another thread resolved the reference, this is a race condition. This + // thread may have had a security manager or something temporary. + // This doesn't deterministically get an error. So why do we save this? + // We save this because jvmti can add classes to the bootclass path after + // this error, so it needs to get the same error if the error is first. jbyte old_tag = Atomic::cmpxchg((jbyte)error_tag, (jbyte*)this_cp->tag_addr_at(which), (jbyte)tag.value()); - assert(old_tag == error_tag || old_tag == tag.value(), "should not be resolved otherwise"); + if (old_tag != error_tag && old_tag != tag.value()) { + // MethodHandles and MethodType doesn't change to resolved version. + assert(this_cp->tag_at(which).is_klass(), "Wrong tag value"); + // Forget the exception and use the resolved class. + CLEAR_PENDING_EXCEPTION; + } } else { // some other thread put this in error state throw_resolution_error(this_cp, which, CHECK); } - - // This exits with some pending exception - assert(HAS_PENDING_EXCEPTION, "should not be cleared"); } - - // Called to resolve constants in the constant pool and return an oop. // Some constant pool entries cache their resolved oop. This is also // called to create oops from constants to use in arguments for invokedynamic @@ -627,7 +640,7 @@ oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_cp, int index case JVM_CONSTANT_Class: { assert(cache_index == _no_index_sentinel, "should not have been set"); - Klass* resolved = klass_at_impl(this_cp, index, CHECK_NULL); + Klass* resolved = klass_at_impl(this_cp, index, true, CHECK_NULL); // ldc wants the java mirror. result_oop = resolved->java_mirror(); break; @@ -660,7 +673,7 @@ oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_cp, int index ref_kind, index, this_cp->method_handle_index_at(index), callee_index, name->as_C_string(), signature->as_C_string()); KlassHandle callee; - { Klass* k = klass_at_impl(this_cp, callee_index, CHECK_NULL); + { Klass* k = klass_at_impl(this_cp, callee_index, true, CHECK_NULL); callee = KlassHandle(THREAD, k); } KlassHandle klass(THREAD, this_cp->pool_holder()); diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp index 5e26ec5e622..18b86aa7ac6 100644 --- a/hotspot/src/share/vm/oops/constantPool.hpp +++ b/hotspot/src/share/vm/oops/constantPool.hpp @@ -336,7 +336,13 @@ class ConstantPool : public Metadata { Klass* klass_at(int which, TRAPS) { constantPoolHandle h_this(THREAD, this); - return klass_at_impl(h_this, which, CHECK_NULL); + return klass_at_impl(h_this, which, true, CHECK_NULL); + } + + // Version of klass_at that doesn't save the resolution error, called during deopt + Klass* klass_at_ignore_error(int which, TRAPS) { + constantPoolHandle h_this(THREAD, this); + return klass_at_impl(h_this, which, false, CHECK_NULL); } Symbol* klass_name_at(int which); // Returns the name, w/o resolving. @@ -793,7 +799,8 @@ class ConstantPool : public Metadata { // Implementation of methods that needs an exposed 'this' pointer, in order to // handle GC while executing the method - static Klass* klass_at_impl(constantPoolHandle this_cp, int which, TRAPS); + static Klass* klass_at_impl(constantPoolHandle this_cp, int which, + bool save_resolution_error, TRAPS); static oop string_at_impl(constantPoolHandle this_cp, int which, int obj_index, TRAPS); static void trace_class_resolution(constantPoolHandle this_cp, KlassHandle k); diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp index b94b7142b7e..95587bff533 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.cpp +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp @@ -1173,7 +1173,7 @@ Deoptimization::get_method_data(JavaThread* thread, methodHandle m, void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) { // in case of an unresolved klass entry, load the class. if (constant_pool->tag_at(index).is_unresolved_klass()) { - Klass* tk = constant_pool->klass_at(index, CHECK); + Klass* tk = constant_pool->klass_at_ignore_error(index, CHECK); return; } From 8d64173ec8b8722010f4e986c4f9af093894affd Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Tue, 28 Oct 2014 17:14:43 -0400 Subject: [PATCH 41/67] 8048124: Read hijra-config-umalqura.properties as a resource Removed use of calendar.properties to configure calendars, move UmmAlQura calendar to resource Reviewed-by: alanb --- make/CompileJavaModules.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/CompileJavaModules.gmk b/make/CompileJavaModules.gmk index a29dc2ec4d8..3ef60a4fc04 100644 --- a/make/CompileJavaModules.gmk +++ b/make/CompileJavaModules.gmk @@ -42,7 +42,7 @@ java.activation_SETUP := GENERATE_JDKBYTECODE_NOWARNINGS ################################################################################ -java.base_COPY := .icu .dat .spp content-types.properties +java.base_COPY := .icu .dat .spp content-types.properties hijrah-config-islamic-umalqura.properties java.base_CLEAN := intrinsic.properties java.base_EXCLUDES += java/lang/doc-files From b587478f7cc14d8ba426dbd22db00f5a5a21320b Mon Sep 17 00:00:00 2001 From: Richard Warburton Date: Wed, 29 Oct 2014 12:09:17 +0100 Subject: [PATCH 42/67] 8062376: Suppress cast warnings when using NIO buffers Reviewed-by: psandoz, jfranck --- .../classes/com/sun/tools/javac/file/JavacFileManager.java | 1 + .../classes/com/sun/tools/javac/util/BaseFileManager.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java index 24ead9af4dc..72c6574410e 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -76,6 +76,7 @@ import static javax.tools.StandardLocation.*; */ public class JavacFileManager extends BaseFileManager implements StandardJavaFileManager { + @SuppressWarnings("cast") public static char[] toArray(CharBuffer buffer) { if (buffer.hasArray()) return ((CharBuffer)buffer.compact().flip()).array(); diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BaseFileManager.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BaseFileManager.java index 13ebfd2d619..0959ce7dec3 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BaseFileManager.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BaseFileManager.java @@ -235,6 +235,7 @@ public abstract class BaseFileManager implements JavaFileManager { return encName; } + @SuppressWarnings("cast") public CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { String encodingName = getEncodingName(); CharsetDecoder decoder; @@ -315,6 +316,7 @@ public abstract class BaseFileManager implements JavaFileManager { * @return a byte buffer containing the contents of the stream * @throws IOException if an error occurred while reading the stream */ + @SuppressWarnings("cast") public ByteBuffer makeByteBuffer(InputStream in) throws IOException { int limit = in.available(); @@ -343,6 +345,7 @@ public abstract class BaseFileManager implements JavaFileManager { /** * A single-element cache of direct byte buffers. */ + @SuppressWarnings("cast") private static class ByteBufferCache { private ByteBuffer cached; ByteBuffer get(int capacity) { From 9299e8a8a6f740c631bb160c066ce3fddb0f694b Mon Sep 17 00:00:00 2001 From: Florian Bruckner Date: Wed, 29 Oct 2014 11:53:37 +0000 Subject: [PATCH 43/67] 8062264: KeychainStore requires non-null password to be supplied when retrieving a private key Reviewed-by: mullan --- .../classes/apple/security/KeychainStore.java | 17 +++++- .../tools/keytool/ExportPrivateKeyNoPwd.java | 57 +++++++++++++++++++ .../tools/keytool/ListKeychainStore.sh | 37 ++++++++---- 3 files changed, 98 insertions(+), 13 deletions(-) create mode 100644 jdk/test/sun/security/tools/keytool/ExportPrivateKeyNoPwd.java diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java b/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java index 8d04ee976f6..286c05136ab 100644 --- a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java +++ b/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java @@ -140,7 +140,8 @@ public final class KeychainStore extends KeyStoreSpi { * password to recover it. * * @param alias the alias name - * @param password the password for recovering the key + * @param password the password for recovering the key. This password is + * used internally as the key is exported in a PKCS12 format. * * @return the requested key, or null if the given alias does not exist * or does not identify a key entry. @@ -155,6 +156,20 @@ public final class KeychainStore extends KeyStoreSpi { { permissionCheck(); + // An empty password is rejected by MacOS API, no private key data + // is exported. If no password is passed (as is the case when + // this implementation is used as browser keystore in various + // deployment scenarios like Webstart, JFX and applets), create + // a dummy password so MacOS API is happy. + if (password == null || password.length == 0) { + // Must not be a char array with only a 0, as this is an empty + // string. + if (random == null) { + random = new SecureRandom(); + } + password = Long.toString(random.nextLong()).toCharArray(); + } + Object entry = entries.get(alias.toLowerCase()); if (entry == null || !(entry instanceof KeyEntry)) { diff --git a/jdk/test/sun/security/tools/keytool/ExportPrivateKeyNoPwd.java b/jdk/test/sun/security/tools/keytool/ExportPrivateKeyNoPwd.java new file mode 100644 index 00000000000..799bf455b23 --- /dev/null +++ b/jdk/test/sun/security/tools/keytool/ExportPrivateKeyNoPwd.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.security.*; + +/* + * Export a private key from the named keychain entry without supplying a + * password. See JDK-8062264. + * + * NOTE: Keychain access controls must already have been lowered to permit + * the target entry to be accessed. + */ +public class ExportPrivateKeyNoPwd { + + public static final void main(String[] args) throws Exception { + + if (args.length != 1) { + throw new Exception( + "ExportPrivateKeyNoPwd: must supply name of a keystore entry"); + } + String alias = args[0]; + + KeyStore ks = KeyStore.getInstance("KeychainStore"); + System.out.println("ExportPrivateKeyNoPwd: loading keychains..."); + ks.load(null, null); + + System.out.println("ExportPrivateKeyNoPwd: exporting key..."); + Key key = ks.getKey(alias, null); + if (key instanceof PrivateKey) { + System.out.println("ExportPrivateKeyNoPwd: exported " + + key.getAlgorithm() + " private key from '" + alias + "'"); + } else { + throw new Exception("Error exporting private key from keychain"); + } + } +} + diff --git a/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh b/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh index ff82364ddd2..e7e65cd01ba 100644 --- a/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh +++ b/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh @@ -22,7 +22,7 @@ # # @test -# @bug 7133495 8041740 +# @bug 7133495 8041740 8062264 # @summary [macosx] KeyChain KeyStore implementation retrieves only one private key entry if [ "${TESTJAVA}" = "" ] ; then @@ -30,6 +30,9 @@ if [ "${TESTJAVA}" = "" ] ; then TESTJAVA=`dirname $JAVAC_CMD`/.. fi +if [ "${TESTSRC}" = "" ] ; then + TESTSRC="." +fi if [ "${TESTCLASSES}" = "" ] ; then TESTCLASSES=`pwd` fi @@ -59,10 +62,6 @@ CLEANUP_LIST="rm -f $TEMPORARY_LIST" COUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l` echo "Found $COUNT private key entries in the Keychain keystores" -if [ $COUNT -gt 1 ]; then - exit 0 -fi - # Create a temporary PKCS12 keystore containing 3 public/private keypairs RESULT=`$CLEANUP_P12` @@ -107,8 +106,9 @@ fi echo "Unlocked the temporary keychain" # Import the keypairs from the PKCS12 keystore into the keychain +# (The '-A' option is used to lower the temporary keychain's access controls) -security import $TEMPORARY_P12 -k $TEMPORARY_KC -f pkcs12 -P $PWD +security import $TEMPORARY_P12 -k $TEMPORARY_KC -f pkcs12 -P $PWD -A if [ $? -ne 0 ]; then echo "Error: cannot import keypairs from PKCS12 keystore into the keychain" RESULT=`$CLEANUP_P12` @@ -128,26 +128,39 @@ security list-keychains # Recount the number of private key entries in the Keychain keystores -COUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l` -echo "Found $COUNT private key entries in the Keychain keystore" -if [ $COUNT -lt 3 ]; then - echo "Error: expected >2 private key entries in the Keychain keystores" +RECOUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l` +echo "Found $RECOUNT private key entries in the Keychain keystore" +if [ $RECOUNT -lt `expr $COUNT + 3` ]; then + echo "Error: expected >$COUNT private key entries in the Keychain keystores" RESULT=`$CLEANUP_P12` RESULT=`$CLEANUP_KC` exit 5 fi +# Export a private key from the keychain (without supplying a password) +# Access controls have already been lowered (see 'security import ... -A' above) + +${TESTJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . ${TESTSRC}/ExportPrivateKeyNoPwd.java || exit 6 +echo | ${TESTJAVA}/bin/java ${TESTVMOPTS} ExportPrivateKeyNoPwd x +if [ $? -ne 0 ]; then + echo "Error exporting private key from the temporary keychain" + RESULT=`$CLEANUP_P12` + RESULT=`$CLEANUP_KC` + exit 6 +fi +echo "Exported a private key from the temporary keychain" + RESULT=`$CLEANUP_P12` if [ $? -ne 0 ]; then echo "Error: cannot remove the temporary PKCS12 keystore" - exit 6 + exit 7 fi echo "Removed the temporary PKCS12 keystore" RESULT=`$CLEANUP_KC` if [ $? -ne 0 ]; then echo "Error: cannot remove the temporary keychain" - exit 7 + exit 8 fi echo "Removed the temporary keychain" From a065473cfc12ad2b1492372d054c76ad8fa04a1a Mon Sep 17 00:00:00 2001 From: Richard Warburton Date: Wed, 29 Oct 2014 14:10:34 +0100 Subject: [PATCH 44/67] 4774077: Use covariant return types in the NIO buffer hierarchy Reviewed-by: psandoz, alanb, mr, darcy --- .../share/classes/java/nio/Buffer.java | 14 +-- .../classes/java/nio/MappedByteBuffer.java | 72 +++++++++++++ .../classes/java/nio/X-Buffer.java.template | 100 ++++++++++++++++++ .../classes/sun/security/ssl/CipherBox.java | 4 +- .../sun/security/ssl/EngineInputRecord.java | 3 +- .../sun/security/ssl/EngineOutputRecord.java | 4 +- jdk/test/java/io/FileDescriptor/Finalize.java | 7 +- .../nio/charset/CharsetEncoder/Flush.java | 2 +- jdk/test/sun/nio/cs/TestUTF_16.java | 2 +- jdk/test/sun/nio/cs/TestUTF_32.java | 2 +- 10 files changed, 190 insertions(+), 20 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/nio/Buffer.java b/jdk/src/java.base/share/classes/java/nio/Buffer.java index 2a90de84610..37d8aa0786c 100644 --- a/jdk/src/java.base/share/classes/java/nio/Buffer.java +++ b/jdk/src/java.base/share/classes/java/nio/Buffer.java @@ -239,7 +239,7 @@ public abstract class Buffer { * @throws IllegalArgumentException * If the preconditions on newPosition do not hold */ - public final Buffer position(int newPosition) { + public Buffer position(int newPosition) { if ((newPosition > limit) || (newPosition < 0)) throw new IllegalArgumentException(); position = newPosition; @@ -270,7 +270,7 @@ public abstract class Buffer { * @throws IllegalArgumentException * If the preconditions on newLimit do not hold */ - public final Buffer limit(int newLimit) { + public Buffer limit(int newLimit) { if ((newLimit > capacity) || (newLimit < 0)) throw new IllegalArgumentException(); limit = newLimit; @@ -284,7 +284,7 @@ public abstract class Buffer { * * @return This buffer */ - public final Buffer mark() { + public Buffer mark() { mark = position; return this; } @@ -300,7 +300,7 @@ public abstract class Buffer { * @throws InvalidMarkException * If the mark has not been set */ - public final Buffer reset() { + public Buffer reset() { int m = mark; if (m < 0) throw new InvalidMarkException(); @@ -325,7 +325,7 @@ public abstract class Buffer { * * @return This buffer */ - public final Buffer clear() { + public Buffer clear() { position = 0; limit = capacity; mark = -1; @@ -353,7 +353,7 @@ public abstract class Buffer { * * @return This buffer */ - public final Buffer flip() { + public Buffer flip() { limit = position; position = 0; mark = -1; @@ -375,7 +375,7 @@ public abstract class Buffer { * * @return This buffer */ - public final Buffer rewind() { + public Buffer rewind() { position = 0; mark = -1; return this; diff --git a/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java b/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java index 4d52d90e25f..5331cb372da 100644 --- a/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java +++ b/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java @@ -208,4 +208,76 @@ public abstract class MappedByteBuffer private native boolean isLoaded0(long address, long length, int pageCount); private native void load0(long address, long length); private native void force0(FileDescriptor fd, long address, long length); + + // -- Covariant return type overrides + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer position(int newPosition) { + super.position(newPosition); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer limit(int newLimit) { + super.limit(newLimit); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer mark() { + super.mark(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer reset() { + super.reset(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer clear() { + super.clear(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer flip() { + super.flip(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer rewind() { + super.rewind(); + return this; + } } diff --git a/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template b/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template index b45f9ad3050..984bc1ee052 100644 --- a/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template +++ b/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template @@ -1025,6 +1025,106 @@ public abstract class $Type$Buffer return offset; } + // -- Covariant return type overrides + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer position(int newPosition) { + super.position(newPosition); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer limit(int newLimit) { + super.limit(newLimit); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer mark() { + super.mark(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer reset() { + super.reset(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer clear() { + super.clear(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer flip() { + super.flip(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer rewind() { + super.rewind(); + return this; + } + /** * Compacts this buffer  (optional operation). * diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java index fa11bce3f30..e9f22055bb9 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java @@ -560,7 +560,7 @@ final class CipherBox { + newLen); hd.encodeBuffer( - (ByteBuffer)bb.duplicate().position(pos), System.out); + bb.duplicate().position(pos), System.out); } catch (IOException e) { } } @@ -790,7 +790,7 @@ final class CipherBox { // The padding data should be filled with the padding length value. int[] results = checkPadding( - (ByteBuffer)bb.duplicate().position(offset + newLen), + bb.duplicate().position(offset + newLen), (byte)(padLen & 0xFF)); if (protocolVersion.v >= ProtocolVersion.TLS10.v) { if (results[0] != 0) { // padding data has invalid bytes diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/EngineInputRecord.java b/jdk/src/java.base/share/classes/sun/security/ssl/EngineInputRecord.java index d980b162972..e5c20a31308 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/EngineInputRecord.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/EngineInputRecord.java @@ -349,8 +349,7 @@ final class EngineInputRecord extends InputRecord { /* * Copy data out of buffer, it's ready to go. */ - ByteBuffer netBB = (ByteBuffer) - (ByteBuffer.allocate(len).put(buf, 0, len).flip()); + ByteBuffer netBB = ByteBuffer.allocate(len).put(buf, 0, len).flip(); engine.writer.putOutboundDataSync(netBB); } diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/EngineOutputRecord.java b/jdk/src/java.base/share/classes/sun/security/ssl/EngineOutputRecord.java index 686accac461..02770eaf4b1 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/EngineOutputRecord.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/EngineOutputRecord.java @@ -113,9 +113,7 @@ final class EngineOutputRecord extends OutputRecord { /* * Copy data out of buffer, it's ready to go. */ - ByteBuffer netBB = (ByteBuffer) - ByteBuffer.allocate(len).put(buf, off, len).flip(); - + ByteBuffer netBB = ByteBuffer.allocate(len).put(buf, off, len).flip(); writer.putOutboundData(netBB); } diff --git a/jdk/test/java/io/FileDescriptor/Finalize.java b/jdk/test/java/io/FileDescriptor/Finalize.java index 04f89103433..607b53860af 100644 --- a/jdk/test/java/io/FileDescriptor/Finalize.java +++ b/jdk/test/java/io/FileDescriptor/Finalize.java @@ -245,9 +245,10 @@ public class Finalize { * write to fc2 - when fos1 is gc'ed and finalizer is run, * write to fc2 should not fail */ - bb = ByteBuffer.allocateDirect(data.length); - bb = bb.put(data); - bb = (ByteBuffer) bb.flip(); + bb = ByteBuffer.allocateDirect(data.length) + .put(data) + .flip(); + ret = fc2.write(bb); System.out.println("Wrote:" + ret + " bytes to fc2"); fc2.close(); diff --git a/jdk/test/java/nio/charset/CharsetEncoder/Flush.java b/jdk/test/java/nio/charset/CharsetEncoder/Flush.java index 0b398d0c6b4..02aad13d302 100644 --- a/jdk/test/java/nio/charset/CharsetEncoder/Flush.java +++ b/jdk/test/java/nio/charset/CharsetEncoder/Flush.java @@ -35,7 +35,7 @@ import java.nio.charset.*; public class Flush { private static byte[] contents(ByteBuffer bb) { byte[] contents = new byte[bb.position()]; - ((ByteBuffer)(bb.duplicate().flip())).get(contents); + bb.duplicate().flip().get(contents); return contents; } diff --git a/jdk/test/sun/nio/cs/TestUTF_16.java b/jdk/test/sun/nio/cs/TestUTF_16.java index 5b4ffb4e5f2..25344ddc802 100644 --- a/jdk/test/sun/nio/cs/TestUTF_16.java +++ b/jdk/test/sun/nio/cs/TestUTF_16.java @@ -150,7 +150,7 @@ public class TestUTF_16 { if (CoderResult.OVERFLOW != Charset.forName("UTF_16") .newDecoder() - .decode((ByteBuffer)(ByteBuffer.allocate(4) + .decode((ByteBuffer.allocate(4) .put(new byte[] {(byte)0xd8,(byte)0x00, (byte)0xdc,(byte)0x01}) diff --git a/jdk/test/sun/nio/cs/TestUTF_32.java b/jdk/test/sun/nio/cs/TestUTF_32.java index 082b244c9f6..3179768957e 100644 --- a/jdk/test/sun/nio/cs/TestUTF_32.java +++ b/jdk/test/sun/nio/cs/TestUTF_32.java @@ -184,7 +184,7 @@ public class TestUTF_32 { if (CoderResult.OVERFLOW != Charset.forName("UTF_32") .newDecoder() - .decode((ByteBuffer)(ByteBuffer.allocate(4) + .decode((ByteBuffer.allocate(4) .put(new byte[] {(byte)0,(byte)1, (byte)0,(byte)01}) .flip()), From 97fc6cb4fae408072ce23997b40fbc30ed303a8e Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Wed, 29 Oct 2014 14:51:51 +0100 Subject: [PATCH 45/67] 8062312: OpenJDK build fails when bundling freetype libraries Reviewed-by: prr, erikj --- jdk/make/copy/Copy-java.desktop.gmk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/make/copy/Copy-java.desktop.gmk b/jdk/make/copy/Copy-java.desktop.gmk index 13658ca2a8a..b3fd662bf9c 100644 --- a/jdk/make/copy/Copy-java.desktop.gmk +++ b/jdk/make/copy/Copy-java.desktop.gmk @@ -67,8 +67,11 @@ ifneq ($(FREETYPE_BUNDLE_LIB_PATH), ) FREETYPE_TARGET_LIB := $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/$(call SHARED_LIBRARY,freetype).6 endif + # We can't use $(install-file) in this rule because it preserves symbolic links and + # libfreetype.so is usually a symbolic link to something like libfreetype.so.6 on Unix. $(FREETYPE_TARGET_LIB): $(FREETYPE_BUNDLE_LIB_PATH)/$(call SHARED_LIBRARY,freetype) - $(install-file) + $(MKDIR) -p $(@D) + $(CP) $< $@ ifeq ($(OPENJDK_BUILD_OS), windows) $(CHMOD) +rx $@ endif From 8b8a9d5f943c9532ac5603dfe318e513fb732912 Mon Sep 17 00:00:00 2001 From: Sergei Kovalev Date: Wed, 29 Oct 2014 17:53:36 +0300 Subject: [PATCH 46/67] 8060707: jdwp accept invalid address ':' Reviewed-by: jbachorik, dsamersoff, iignatyev, miauno --- jdk/test/com/sun/jdi/OptionTest.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jdk/test/com/sun/jdi/OptionTest.java b/jdk/test/com/sun/jdi/OptionTest.java index 054047f2c48..3278588a3e5 100644 --- a/jdk/test/com/sun/jdi/OptionTest.java +++ b/jdk/test/com/sun/jdi/OptionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, 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 @@ -34,9 +34,11 @@ */ import java.net.ServerSocket; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class OptionTest extends Object { - private Process subprocess; + private static final Pattern TRANSPORT_ERROR_PTRN = Pattern.compile("^ERROR: transport error .+$", Pattern.MULTILINE); private int subprocessStatus; private static final String CR = System.getProperty("line.separator"); private static final int BUFFERSIZE = 4096; @@ -153,7 +155,7 @@ public class OptionTest extends Object { OptionTest myTest = new OptionTest(); String results [] = myTest.run(VMConnection.insertDebuggeeVMOptions(cmds)); if (!(results[RETSTAT].equals("0")) || - (results[STDERR].startsWith("ERROR:"))) { + (TRANSPORT_ERROR_PTRN.matcher(results[STDERR]).find())) { throw new Exception("Test failed: jdwp doesn't like " + cmds[1]); } } @@ -179,7 +181,7 @@ public class OptionTest extends Object { OptionTest myTest = new OptionTest(); String results[] = myTest.run(VMConnection.insertDebuggeeVMOptions(cmds)); - if (!results[RETSTAT].equals("0") && results[STDERR].startsWith("ERROR:")) { + if (!results[RETSTAT].equals("0") && TRANSPORT_ERROR_PTRN.matcher(results[STDERR]).find()) { // We got expected error, test passed } else { From 426cd00f3b92cf5d5e70933330c509e20b15e1b1 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov Date: Wed, 29 Oct 2014 19:59:53 +0300 Subject: [PATCH 47/67] 8059206: (tz) Support tzdata2014i Reviewed-by: okutsu --- jdk/make/data/tzdata/VERSION | 2 +- jdk/make/data/tzdata/africa | 57 +++++-------- jdk/make/data/tzdata/asia | 82 ++++++++++++++----- jdk/make/data/tzdata/australasia | 44 ++++++++-- jdk/make/data/tzdata/europe | 15 +++- jdk/make/data/tzdata/northamerica | 41 +++++++--- jdk/make/data/tzdata/zone.tab | 3 +- .../sun/util/resources/TimeZoneNames.java | 5 +- .../util/resources/de/TimeZoneNames_de.java | 5 +- .../util/resources/es/TimeZoneNames_es.java | 5 +- .../util/resources/fr/TimeZoneNames_fr.java | 5 +- .../util/resources/it/TimeZoneNames_it.java | 5 +- .../util/resources/ja/TimeZoneNames_ja.java | 5 +- .../util/resources/ko/TimeZoneNames_ko.java | 5 +- .../resources/pt/TimeZoneNames_pt_BR.java | 5 +- .../util/resources/sv/TimeZoneNames_sv.java | 5 +- .../resources/zh/TimeZoneNames_zh_CN.java | 5 +- .../resources/zh/TimeZoneNames_zh_TW.java | 5 +- 18 files changed, 206 insertions(+), 93 deletions(-) diff --git a/jdk/make/data/tzdata/VERSION b/jdk/make/data/tzdata/VERSION index 5e925ada8df..fa498de5234 100644 --- a/jdk/make/data/tzdata/VERSION +++ b/jdk/make/data/tzdata/VERSION @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2014g +tzdata2014i diff --git a/jdk/make/data/tzdata/africa b/jdk/make/data/tzdata/africa index aa91f365ce1..92c0d4728f3 100644 --- a/jdk/make/data/tzdata/africa +++ b/jdk/make/data/tzdata/africa @@ -133,23 +133,13 @@ Zone Africa/Algiers 0:12:12 - LMT 1891 Mar 15 0:01 # See Africa/Lagos. # Botswana -# From Paul Eggert (2013-02-21): -# Milne says they were regulated by the Cape Town Signal in 1899; -# assume they switched to 2:00 when Cape Town did. -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Gaborone 1:43:40 - LMT 1885 - 1:30 - SAST 1903 Mar - 2:00 - CAT 1943 Sep 19 2:00 - 2:00 1:00 CAST 1944 Mar 19 2:00 - 2:00 - CAT +# See Africa/Maputo. # Burkina Faso # See Africa/Abidjan. # Burundi -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Bujumbura 1:57:28 - LMT 1890 - 2:00 - CAT +# See Africa/Maputo. # Cameroon # See Africa/Lagos. @@ -184,10 +174,7 @@ Zone Indian/Comoro 2:53:04 - LMT 1911 Jul # Moroni, Gran Comoro 3:00 - EAT # Democratic Republic of the Congo -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Lubumbashi 1:49:52 - LMT 1897 Nov 9 - 2:00 - CAT -# The above is for the eastern part; see Africa/Lagos for the western part. +# See Africa/Lagos for the western part and Africa/Maputo for the eastern. # Republic of the Congo # See Africa/Lagos. @@ -339,7 +326,7 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 0 - # Egypt is to change back to Daylight system on May 15 # http://english.ahram.org.eg/NewsContent/1/64/100735/Egypt/Politics-/Egypts-government-to-reapply-daylight-saving-time-.aspx -# From Gunther Vermier (2015-05-13): +# From Gunther Vermier (2014-05-13): # our Egypt office confirms that the change will be at 15 May "midnight" (24:00) # From Imed Chihi (2014-06-04): @@ -489,11 +476,7 @@ Zone Africa/Nairobi 2:27:16 - LMT 1928 Jul 3:00 - EAT # Lesotho -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Maseru 1:50:00 - LMT 1903 Mar - 2:00 - SAST 1943 Sep 19 2:00 - 2:00 1:00 SAST 1944 Mar 19 2:00 - 2:00 - SAST +# See Africa/Johannesburg. # Liberia # From Paul Eggert (2006-03-22): @@ -575,9 +558,7 @@ Zone Indian/Antananarivo 3:10:04 - LMT 1911 Jul 3:00 - EAT # Malawi -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Blantyre 2:20:00 - LMT 1903 Mar - 2:00 - CAT +# See Africa/Maputo. # Mali # Mauritania @@ -987,6 +968,13 @@ Zone Africa/El_Aaiun -0:52:48 - LMT 1934 Jan # El Aaiún # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Maputo 2:10:20 - LMT 1903 Mar 2:00 - CAT +Link Africa/Maputo Africa/Blantyre # Malawi +Link Africa/Maputo Africa/Bujumbura # Burundi +Link Africa/Maputo Africa/Gaborone # Botswana +Link Africa/Maputo Africa/Harare # Zimbabwe +Link Africa/Maputo Africa/Kigali # Rwanda +Link Africa/Maputo Africa/Lubumbashi # E Dem. Rep. of Congo +Link Africa/Maputo Africa/Lusaka # Zambia # Namibia # The 1994-04-03 transition is from Shanks & Pottenger. @@ -1054,9 +1042,7 @@ Zone Indian/Reunion 3:41:52 - LMT 1911 Jun # Saint-Denis # Tromelin - inhabited until at least 1958 # Rwanda -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Kigali 2:00:16 - LMT 1935 Jun - 2:00 - CAT +# See Africa/Maputo. # St Helena # See Africa/Abidjan. @@ -1100,6 +1086,9 @@ Rule SA 1943 1944 - Mar Sun>=15 2:00 0 - Zone Africa/Johannesburg 1:52:00 - LMT 1892 Feb 8 1:30 - SAST 1903 Mar 2:00 SA SAST +Link Africa/Johannesburg Africa/Maseru # Lesotho +Link Africa/Johannesburg Africa/Mbabane # Swaziland +# # Marion and Prince Edward Is # scientific station since 1947 # no information @@ -1127,9 +1116,7 @@ Zone Africa/Khartoum 2:10:08 - LMT 1931 Link Africa/Khartoum Africa/Juba # Swaziland -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Mbabane 2:04:24 - LMT 1903 Mar - 2:00 - SAST +# See Africa/Johannesburg. # Tanzania # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -1250,11 +1237,5 @@ Zone Africa/Kampala 2:09:40 - LMT 1928 Jul 3:00 - EAT # Zambia -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Lusaka 1:53:08 - LMT 1903 Mar - 2:00 - CAT - # Zimbabwe -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Harare 2:04:12 - LMT 1903 Mar - 2:00 - CAT +# See Africa/Maputo. diff --git a/jdk/make/data/tzdata/asia b/jdk/make/data/tzdata/asia index 906c0a97cda..31754b2d567 100644 --- a/jdk/make/data/tzdata/asia +++ b/jdk/make/data/tzdata/asia @@ -70,10 +70,11 @@ # 3:30 IRST IRDT Iran # 4:00 GST Gulf* # 5:30 IST India -# 7:00 ICT Indochina* +# 7:00 ICT Indochina, most times and locations* # 7:00 WIB west Indonesia (Waktu Indonesia Barat) # 8:00 WITA central Indonesia (Waktu Indonesia Tengah) # 8:00 CST China +# 8:00 IDT Indochina, 1943-45, 1947-55, 1960-75 (some locations)* # 8:00 JWST Western Standard Time (Japan, 1896/1937)* # 9:00 JCST Central Standard Time (Japan, 1896/1937) # 9:00 WIT east Indonesia (Waktu Indonesia Timur) @@ -294,12 +295,8 @@ Zone Asia/Rangoon 6:24:40 - LMT 1880 # or Yangon 6:30 - MMT # Myanmar Time # Cambodia -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Phnom_Penh 6:59:40 - LMT 1906 Jun 9 - 7:06:20 - SMT 1911 Mar 11 0:01 # Saigon MT? - 7:00 - ICT 1912 May - 8:00 - ICT 1931 May - 7:00 - ICT +# See Asia/Bangkok. + # China @@ -916,6 +913,10 @@ Zone Asia/Kolkata 5:53:28 - LMT 1880 # Kolkata # Indonesia # +# From Paul Eggert (2014-09-06): +# The 1876 Report of the Secretary of the [US] Navy, p 306 says that Batavia +# civil time was 7:07:12.5; round to even for Jakarta. +# # From Gwillim Law (2001-05-28), overriding Shanks & Pottenger: # http://www.sumatera-inc.com/go_to_invest/about_indonesia.asp#standtime # says that Indonesia's time zones changed on 1988-01-01. Looking at some @@ -1733,12 +1734,8 @@ Zone Asia/Kuwait 3:11:56 - LMT 1950 3:00 - AST # Laos -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Vientiane 6:50:24 - LMT 1906 Jun 9 # or Viangchan - 7:06:20 - SMT 1911 Mar 11 0:01 # Saigon MT? - 7:00 - ICT 1912 May - 8:00 - ICT 1931 May - 7:00 - ICT +# See Asia/Bangkok. + # Lebanon # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S @@ -2751,6 +2748,8 @@ Zone Asia/Dushanbe 4:35:12 - LMT 1924 May 2 Zone Asia/Bangkok 6:42:04 - LMT 1880 6:42:04 - BMT 1920 Apr # Bangkok Mean Time 7:00 - ICT +Link Asia/Bangkok Asia/Phnom_Penh # Cambodia +Link Asia/Bangkok Asia/Vientiane # Laos # Turkmenistan # From Shanks & Pottenger. @@ -2788,22 +2787,65 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2 # Vietnam -# From Paul Eggert (2013-02-21): +# From Paul Eggert (2014-10-04): # Milne gives 7:16:56 for the meridian of Saigon in 1899, as being # used in Lower Laos, Cambodia, and Annam. But this is quite a ways # from Saigon's location. For now, ignore this and stick with Shanks -# and Pottenger. +# and Pottenger for LMT before 1906. # From Arthur David Olson (2008-03-18): # The English-language name of Vietnam's most populous city is "Ho Chi Minh # City"; use Ho_Chi_Minh below to avoid a name of more than 14 characters. -# From Shanks & Pottenger: +# From Paul Eggert (2014-10-21) after a heads-up from Trần Ngọc Quân: +# Trần Tiến Bình's authoritative book "Lịch Việt Nam: thế kỷ XX-XXI (1901-2100)" +# (Nhà xuất bản Văn Hoá - Thông Tin, Hanoi, 2005), pp 49-50, +# is quoted verbatim in: +# http://www.thoigian.com.vn/?mPage=P80D01 +# is translated by Brian Inglis in: +# http://mm.icann.org/pipermail/tz/2014-October/021654.html +# and is the basis for the information below. +# +# The 1906 transition was effective July 1 and standardized Indochina to +# Phù Liễn Observatory, legally 104 deg. 17'17" east of Paris. +# It's unclear whether this meant legal Paris Mean Time (00:09:21) or +# the Paris Meridian (2 deg. 20'14.03" E); the former yields 07:06:30.1333... +# and the latter 07:06:29.333... so either way it rounds to 07:06:30, +# which is used below even though the modern-day Phù Liễn Observatory +# is closer to 07:06:31. Abbreviate Phù Liễn Mean Time as PLMT. +# +# The following transitions occurred in Indochina in general (before 1954) +# and in South Vietnam in particular (after 1954): +# To 07:00 on 1911-05-01. +# To 08:00 on 1942-12-31 at 23:00. +# To 09:00 in 1945-03-14 at 23:00. +# To 07:00 on 1945-09-02 in Vietnam. +# To 08:00 on 1947-04-01 in French-controlled Indochina. +# To 07:00 on 1955-07-01 in South Vietnam. +# To 08:00 on 1959-12-31 at 23:00 in South Vietnam. +# To 07:00 on 1975-06-13 in South Vietnam. +# +# Trần cites the following sources; it's unclear which supplied the info above. +# +# Hoàng Xuân Hãn: "Lịch và lịch Việt Nam". Tập san Khoa học Xã hội, +# No. 9, Paris, February 1982. +# +# Lê Thành Lân: "Lịch và niên biểu lịch sử hai mươi thế kỷ (0001-2010)", +# NXB Thống kê, Hanoi, 2000. +# +# Lê Thành Lân: "Lịch hai thế kỷ (1802-2010) và các lịch vĩnh cửu", +# NXB Thuận Hoá, Huế, 1995. + # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Ho_Chi_Minh 7:06:40 - LMT 1906 Jun 9 - 7:06:20 - SMT 1911 Mar 11 0:01 # Saigon MT? - 7:00 - ICT 1912 May - 8:00 - ICT 1931 May +Zone Asia/Ho_Chi_Minh 7:06:40 - LMT 1906 Jul 1 + 7:06:30 - PLMT 1911 May 1 + 7:00 - ICT 1942 Dec 31 23:00 + 8:00 - IDT 1945 Mar 14 23:00 + 9:00 - JST 1945 Sep 2 + 7:00 - ICT 1947 Apr 1 + 8:00 - IDT 1955 Jul 1 + 7:00 - ICT 1959 Dec 31 23:00 + 8:00 - IDT 1975 Jun 13 7:00 - ICT # Yemen diff --git a/jdk/make/data/tzdata/australasia b/jdk/make/data/tzdata/australasia index 52d32904178..c45680ace6a 100644 --- a/jdk/make/data/tzdata/australasia +++ b/jdk/make/data/tzdata/australasia @@ -354,20 +354,27 @@ Zone Indian/Cocos 6:27:40 - LMT 1900 # Fiji will end DST on 2014-01-19 02:00: # http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVINGS-TO-END-THIS-MONTH-%281%29.aspx -# From Paul Eggert (2014-01-10): -# For now, guess that Fiji springs forward the Sunday before the fourth -# Monday in October, and springs back the penultimate Sunday in January. -# This is ad hoc, but matches recent practice. +# From Ken Rylander (2014-10-20): +# DST will start Nov. 2 this year. +# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVING-STARTS-ON-SUNDAY,-NOVEMBER-2ND.aspx + +# From Paul Eggert (2014-10-20): +# For now, guess DST from 02:00 the first Sunday in November to +# 03:00 the first Sunday on or after January 18. Although ad hoc, it +# matches this year's plan and seems more likely to match future +# practice than guessing no DST. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Fiji 1998 1999 - Nov Sun>=1 2:00 1:00 S Rule Fiji 1999 2000 - Feb lastSun 3:00 0 - Rule Fiji 2009 only - Nov 29 2:00 1:00 S Rule Fiji 2010 only - Mar lastSun 3:00 0 - -Rule Fiji 2010 max - Oct Sun>=21 2:00 1:00 S +Rule Fiji 2010 2013 - Oct Sun>=21 2:00 1:00 S Rule Fiji 2011 only - Mar Sun>=1 3:00 0 - Rule Fiji 2012 2013 - Jan Sun>=18 3:00 0 - -Rule Fiji 2014 max - Jan Sun>=18 2:00 0 - +Rule Fiji 2014 only - Jan Sun>=18 2:00 0 - +Rule Fiji 2014 max - Nov Sun>=1 2:00 1:00 S +Rule Fiji 2015 max - Jan Sun>=18 3:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva 12:00 Fiji FJ%sT # Fiji Time @@ -542,6 +549,30 @@ Zone Pacific/Palau 8:57:56 - LMT 1901 # Koror Zone Pacific/Port_Moresby 9:48:40 - LMT 1880 9:48:32 - PMMT 1895 # Port Moresby Mean Time 10:00 - PGT # Papua New Guinea Time +# +# From Paul Eggert (2014-10-13): +# Base the Bougainville entry on the Arawa-Kieta region, which appears to have +# the most people even though it was devastated in the Bougainville Civil War. +# +# Although Shanks gives 1942-03-15 / 1943-11-01 for JST, these dates +# are apparently rough guesswork from the starts of military campaigns. +# The World War II entries below are instead based on Arawa-Kieta. +# The Japanese occupied Kieta in July 1942, +# according to the Pacific War Online Encyclopedia +# http://pwencycl.kgbudge.com/B/o/Bougainville.htm +# and seem to have controlled it until their 1945-08-21 surrender. +# +# The Autonomous Region of Bougainville plans to switch from UTC+10 to UTC+11 +# on 2014-12-28 at 02:00. They call UTC+11 "Bougainville Standard Time"; +# abbreviate this as BST. See: +# http://www.bougainville24.com/bougainville-issues/bougainville-gets-own-timezone/ +# +Zone Pacific/Bougainville 10:22:16 - LMT 1880 + 9:48:32 - PMMT 1895 + 10:00 - PGT 1942 Jul + 9:00 - JST 1945 Aug 21 + 10:00 - PGT 2014 Dec 28 2:00 + 11:00 - BST # Pitcairn # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -826,6 +857,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # 10:00 AEST AEDT Eastern Australia # 10:00 ChST Chamorro # 10:30 LHST LHDT Lord Howe* +# 11:00 BST Bougainville* # 11:30 NZMT NZST New Zealand through 1945 # 12:00 NZST NZDT New Zealand 1946-present # 12:15 CHAST Chatham through 1945* diff --git a/jdk/make/data/tzdata/europe b/jdk/make/data/tzdata/europe index 0c5f5667da9..fb24b87a754 100644 --- a/jdk/make/data/tzdata/europe +++ b/jdk/make/data/tzdata/europe @@ -91,10 +91,11 @@ # 0:00 WET WEST WEMT Western Europe # 0:19:32.13 AMT NST Amsterdam, Netherlands Summer (1835-1937)* # 0:20 NET NEST Netherlands (1937-1940)* +# 1:00 BST British Standard (1968-1971) # 1:00 CET CEST CEMT Central Europe # 1:00:14 SET Swedish (1879-1899)* # 2:00 EET EEST Eastern Europe -# 3:00 FET Further-eastern Europe* +# 3:00 FET Further-eastern Europe (2011-2014)* # 3:00 MSK MSD MSM* Moscow # From Peter Ilieve (1994-12-04), @@ -746,6 +747,13 @@ Zone Europe/Vienna 1:05:21 - LMT 1893 Apr # http://www.belta.by/ru/all_news/society/V-Belarusi-otmenjaetsja-perexod-na-sezonnoe-vremja_i_572952.html # http://naviny.by/rubrics/society/2011/09/16/ic_articles_116_175144/ # http://news.tut.by/society/250578.html +# +# From Alexander Bokovoy (2014-10-09): +# Belarussian government decided against changing to winter time.... +# http://eng.belta.by/all_news/society/Belarus-decides-against-adjusting-time-in-Russias-wake_i_76335.html +# From Paul Eggert (2014-10-08): +# Hence Belarus can share time zone abbreviations with Moscow again. +# # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Minsk 1:50:16 - LMT 1880 1:50 - MMT 1924 May 2 # Minsk Mean Time @@ -758,7 +766,8 @@ Zone Europe/Minsk 1:50:16 - LMT 1880 2:00 - EET 1992 Mar 29 0:00s 2:00 1:00 EEST 1992 Sep 27 0:00s 2:00 Russia EE%sT 2011 Mar 27 2:00s - 3:00 - FET + 3:00 - FET 2014 Oct 26 1:00s + 3:00 - MSK # Belgium # @@ -2524,7 +2533,7 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00 # The Kemerovo region will remain at UTC+7 through the 2014-10-26 change, thus # realigning itself with KRAT. -Zone Asia/Novokuznetsk 5:48:48 - NMT 1920 Jan 6 +Zone Asia/Novokuznetsk 5:48:48 - LMT 1924 May 1 6:00 - KRAT 1930 Jun 21 # Krasnoyarsk Time 7:00 Russia KRA%sT 1991 Mar 31 2:00s 6:00 Russia KRA%sT 1992 Jan 19 2:00s diff --git a/jdk/make/data/tzdata/northamerica b/jdk/make/data/tzdata/northamerica index 0dc714aa92d..329b633ba98 100644 --- a/jdk/make/data/tzdata/northamerica +++ b/jdk/make/data/tzdata/northamerica @@ -300,6 +300,12 @@ Zone PST8PDT -8:00 US P%sT # time zone, but we do go by the Eastern time zone because so many people work # in Columbus." +# From Paul Eggert (2014-09-06): +# Monthly Notices of the Royal Astronomical Society 44, 4 (1884-02-08), 208 +# says that New York City Hall time was 3 minutes 58.4 seconds fast of +# Eastern time (i.e., -4:56:01.6) just before the 1883 switch. Round to the +# nearest second. + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER Rule NYC 1920 only - Mar lastSun 2:00 1:00 D Rule NYC 1920 only - Oct lastSun 2:00 0 S @@ -1118,17 +1124,16 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00 # An amendment to the Interpretation Act was registered on February 19/2007.... # http://action.attavik.ca/home/justice-gn/attach/2007/gaz02part2.pdf -# From Paul Eggert (2006-04-25): +# From Paul Eggert (2014-10-18): # H. David Matthews and Mary Vincent's map # "It's about TIME", _Canadian Geographic_ (September-October 1998) -# http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp +# http://www.canadiangeographic.ca/Magazine/SO98/alacarte.asp # contains detailed boundaries for regions observing nonstandard # time and daylight saving time arrangements in Canada circa 1998. # -# INMS, the Institute for National Measurement Standards in Ottawa, has -# information about standard and daylight saving time zones in Canada. -# http://inms-ienm.nrc-cnrc.gc.ca/en/time_services/daylight_saving_e.php -# (updated periodically). +# National Research Council Canada maintains info about time zones and DST. +# http://www.nrc-cnrc.gc.ca/eng/services/time/time_zones.html +# http://www.nrc-cnrc.gc.ca/eng/services/time/faq/index.html#Q5 # Its unofficial information is often taken from Matthews and Vincent. # From Paul Eggert (2006-06-27): @@ -1993,10 +1998,7 @@ Zone America/Creston -7:46:04 - LMT 1884 # [Also see (2001-03-09).] # From Gwillim Law (2005-05-21): -# According to maps at -# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SWE.jpg -# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SSE.jpg -# (both dated 2003), and +# According to ... # http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp # (from a 1998 Canadian Geographic article), the de facto and de jure time # for Southampton Island (at the north end of Hudson Bay) is UTC-5 all year @@ -2005,9 +2007,11 @@ Zone America/Creston -7:46:04 - LMT 1884 # predates the creation of Nunavut, it probably goes back many years.... # The Inuktitut name of Coral Harbour is Sallit, but it's rarely used. # -# From Paul Eggert (2005-07-26): +# From Paul Eggert (2014-10-17): # For lack of better information, assume that Southampton Island observed -# daylight saving only during wartime. +# daylight saving only during wartime. Gwillim Law's email also +# mentioned maps now maintained by National Research Council Canada; +# see above for an up-to-date link. # From Chris Walton (2007-03-01): # ... the community of Resolute (located on Cornwallis Island in @@ -3008,10 +3012,21 @@ Zone America/Tegucigalpa -5:48:52 - LMT 1921 Apr # Shanks & Pottenger give -5:07:12, but Milne records -5:07:10.41 from an # unspecified official document, and says "This time is used throughout the # island". Go with Milne. Round to the nearest second as required by zic. +# +# Shanks & Pottenger give April 28 for the 1974 spring-forward transition, but +# Lance Neita writes that Prime Minister Michael Manley decreed it January 5. +# Assume Neita meant Jan 6 02:00, the same as the US. Neita also writes that +# Manley's supporters associated this act with Manley's nickname "Joshua" +# (recall that in the Bible the sun stood still at Joshua's request), +# and with the Rod of Correction which Manley said he had received from +# Haile Selassie, Emperor of Ethiopia. See: +# Neita L. The politician in all of us. Jamaica Observer 2014-09-20 +# http://www.jamaicaobserver.com/columns/The-politician-in-all-of-us_17573647 +# # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Jamaica -5:07:11 - LMT 1890 # Kingston -5:07:11 - KMT 1912 Feb # Kingston Mean Time - -5:00 - EST 1974 Apr 28 2:00 + -5:00 - EST 1974 -5:00 US E%sT 1984 -5:00 - EST diff --git a/jdk/make/data/tzdata/zone.tab b/jdk/make/data/tzdata/zone.tab index 45351ca8486..0ef9ba869ea 100644 --- a/jdk/make/data/tzdata/zone.tab +++ b/jdk/make/data/tzdata/zone.tab @@ -330,7 +330,8 @@ PE -1203-07703 America/Lima PF -1732-14934 Pacific/Tahiti Society Islands PF -0900-13930 Pacific/Marquesas Marquesas Islands PF -2308-13457 Pacific/Gambier Gambier Islands -PG -0930+14710 Pacific/Port_Moresby +PG -0930+14710 Pacific/Port_Moresby most locations +PG -0613+15534 Pacific/Bougainville Bougainville PH +1435+12100 Asia/Manila PK +2452+06703 Asia/Karachi PL +5215+02100 Europe/Warsaw diff --git a/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java b/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java index 9ab92c93620..679a5c10033 100644 --- a/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java +++ b/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java @@ -829,7 +829,7 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -917,6 +917,9 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, diff --git a/jdk/src/jdk.localedata/share/classes/sun/util/resources/de/TimeZoneNames_de.java b/jdk/src/jdk.localedata/share/classes/sun/util/resources/de/TimeZoneNames_de.java index 9b4e6503d84..83ba779778b 100644 --- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/de/TimeZoneNames_de.java +++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/de/TimeZoneNames_de.java @@ -829,7 +829,7 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -917,6 +917,9 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, diff --git a/jdk/src/jdk.localedata/share/classes/sun/util/resources/es/TimeZoneNames_es.java b/jdk/src/jdk.localedata/share/classes/sun/util/resources/es/TimeZoneNames_es.java index 0235158296c..2b472669498 100644 --- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/es/TimeZoneNames_es.java +++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/es/TimeZoneNames_es.java @@ -829,7 +829,7 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -917,6 +917,9 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, diff --git a/jdk/src/jdk.localedata/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java b/jdk/src/jdk.localedata/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java index 1d8b8561299..41aefbdad90 100644 --- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java +++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java @@ -829,7 +829,7 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -917,6 +917,9 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, diff --git a/jdk/src/jdk.localedata/share/classes/sun/util/resources/it/TimeZoneNames_it.java b/jdk/src/jdk.localedata/share/classes/sun/util/resources/it/TimeZoneNames_it.java index 43035b66ea4..8f350fbf337 100644 --- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/it/TimeZoneNames_it.java +++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/it/TimeZoneNames_it.java @@ -829,7 +829,7 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -917,6 +917,9 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, diff --git a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java index 68bd6c30871..5ae2aa07994 100644 --- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java +++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java @@ -829,7 +829,7 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -917,6 +917,9 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, diff --git a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java index fcfd748153e..a35768503d1 100644 --- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java +++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java @@ -829,7 +829,7 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -917,6 +917,9 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, diff --git a/jdk/src/jdk.localedata/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java b/jdk/src/jdk.localedata/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java index 60664c5b1f1..942081c5315 100644 --- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java +++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java @@ -829,7 +829,7 @@ public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle { {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -917,6 +917,9 @@ public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle { {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", TRUT}, {"Pacific/Easter", EASTER}, diff --git a/jdk/src/jdk.localedata/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java b/jdk/src/jdk.localedata/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java index ab28e0054a0..bd77d58b881 100644 --- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java +++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java @@ -829,7 +829,7 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -917,6 +917,9 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, diff --git a/jdk/src/jdk.localedata/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java b/jdk/src/jdk.localedata/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java index c8f109aec64..c0590e574b1 100644 --- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java +++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java @@ -829,7 +829,7 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -917,6 +917,9 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, diff --git a/jdk/src/jdk.localedata/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java b/jdk/src/jdk.localedata/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java index 696b571ddc3..19c332dea10 100644 --- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java +++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java @@ -831,7 +831,7 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -919,6 +919,9 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER}, From 224c42ee4d4c3027d1f8f0d8b7ecf6646e9418c3 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Wed, 29 Oct 2014 09:31:37 -0700 Subject: [PATCH 48/67] 8059877: GWT branch frequencies pollution due to LF sharing Reviewed-by: psandoz, jrose --- .../lang/invoke/DelegatingMethodHandle.java | 37 +++-- .../lang/invoke/InvokerBytecodeGenerator.java | 9 +- .../classes/java/lang/invoke/LambdaForm.java | 27 +++- .../java/lang/invoke/MethodHandle.java | 5 +- .../java/lang/invoke/MethodHandleImpl.java | 127 +++++++++++++++++- .../java/lang/invoke/MethodHandleStatics.java | 9 +- .../java/lang/invoke/MethodTypeForm.java | 37 ++--- 7 files changed, 210 insertions(+), 41 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java index 63ba8fea5b2..5c874f49741 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java @@ -44,6 +44,10 @@ abstract class DelegatingMethodHandle extends MethodHandle { super(type, chooseDelegatingForm(target)); } + protected DelegatingMethodHandle(MethodType type, LambdaForm form) { + super(type, form); + } + /** Define this to extract the delegated target which supplies the invocation behavior. */ abstract protected MethodHandle getTarget(); @@ -88,14 +92,31 @@ abstract class DelegatingMethodHandle extends MethodHandle { return makeReinvokerForm(target, MethodTypeForm.LF_DELEGATE, DelegatingMethodHandle.class, NF_getTarget); } - /** Create a LF which simply reinvokes a target of the given basic type. */ static LambdaForm makeReinvokerForm(MethodHandle target, int whichCache, Object constraint, NamedFunction getTargetFn) { + String debugString; + switch(whichCache) { + case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break; + case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break; + default: debugString = "MH.reinvoke"; break; + } + // No pre-action needed. + return makeReinvokerForm(target, whichCache, constraint, debugString, true, getTargetFn, null); + } + /** Create a LF which simply reinvokes a target of the given basic type. */ + static LambdaForm makeReinvokerForm(MethodHandle target, + int whichCache, + Object constraint, + String debugString, + boolean forceInline, + NamedFunction getTargetFn, + NamedFunction preActionFn) { MethodType mtype = target.type().basicType(); boolean customized = (whichCache < 0 || mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY); + boolean hasPreAction = (preActionFn != null); LambdaForm form; if (!customized) { form = mtype.form().cachedLambdaForm(whichCache); @@ -105,12 +126,16 @@ abstract class DelegatingMethodHandle extends MethodHandle { final int ARG_BASE = 1; final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); int nameCursor = ARG_LIMIT; + final int PRE_ACTION = hasPreAction ? nameCursor++ : -1; final int NEXT_MH = customized ? -1 : nameCursor++; final int REINVOKE = nameCursor++; LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); assert(names.length == nameCursor); names[THIS_DMH] = names[THIS_DMH].withConstraint(constraint); Object[] targetArgs; + if (hasPreAction) { + names[PRE_ACTION] = new LambdaForm.Name(preActionFn, names[THIS_DMH]); + } if (customized) { targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class); names[REINVOKE] = new LambdaForm.Name(target, targetArgs); // the invoker is the target itself @@ -120,20 +145,14 @@ abstract class DelegatingMethodHandle extends MethodHandle { targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs); } - String debugString; - switch(whichCache) { - case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break; - case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break; - default: debugString = "MH.reinvoke"; break; - } - form = new LambdaForm(debugString, ARG_LIMIT, names); + form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline); if (!customized) { form = mtype.form().setCachedLambdaForm(whichCache, form); } return form; } - private static final NamedFunction NF_getTarget; + static final NamedFunction NF_getTarget; static { try { NF_getTarget = new NamedFunction(DelegatingMethodHandle.class diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 96a302a0dcc..acb5aa91623 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -628,8 +628,13 @@ class InvokerBytecodeGenerator { // Mark this method as a compiled LambdaForm mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true); - // Force inlining of this invoker method. - mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true); + if (lambdaForm.forceInline) { + // Force inlining of this invoker method. + mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true); + } else { + mv.visitAnnotation("Ljava/lang/invoke/DontInline;", true); + } + // iterate over the form's names, generating bytecode instructions for each // start iterating at the first name following the arguments diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java index b83040647c5..e1791719c0d 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java @@ -119,6 +119,7 @@ import static java.lang.invoke.MethodHandleNatives.Constants.*; class LambdaForm { final int arity; final int result; + final boolean forceInline; @Stable final Name[] names; final String debugName; MemberName vmentry; // low-level behavior, or null if not yet prepared @@ -243,11 +244,16 @@ class LambdaForm { LambdaForm(String debugName, int arity, Name[] names, int result) { + this(debugName, arity, names, result, true); + } + LambdaForm(String debugName, + int arity, Name[] names, int result, boolean forceInline) { assert(namesOK(arity, names)); this.arity = arity; this.result = fixResult(result, names); this.names = names.clone(); this.debugName = fixDebugName(debugName); + this.forceInline = forceInline; int maxOutArity = normalize(); if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) { // Cannot use LF interpreter on very high arity expressions. @@ -255,17 +261,23 @@ class LambdaForm { compileToBytecode(); } } - LambdaForm(String debugName, int arity, Name[] names) { - this(debugName, - arity, names, LAST_RESULT); + this(debugName, arity, names, LAST_RESULT, true); + } + LambdaForm(String debugName, + int arity, Name[] names, boolean forceInline) { + this(debugName, arity, names, LAST_RESULT, forceInline); } - LambdaForm(String debugName, Name[] formals, Name[] temps, Name result) { this(debugName, - formals.length, buildNames(formals, temps, result), LAST_RESULT); + formals.length, buildNames(formals, temps, result), LAST_RESULT, true); + } + LambdaForm(String debugName, + Name[] formals, Name[] temps, Name result, boolean forceInline) { + this(debugName, + formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline); } private static Name[] buildNames(Name[] formals, Name[] temps, Name result) { @@ -279,6 +291,10 @@ class LambdaForm { } private LambdaForm(String sig) { + this(sig, true); + } + + private LambdaForm(String sig, boolean forceInline) { // Make a blank lambda form, which returns a constant zero or null. // It is used as a template for managing the invocation of similar forms that are non-empty. // Called only from getPreparedForm. @@ -287,6 +303,7 @@ class LambdaForm { this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity); this.names = buildEmptyNames(arity, sig); this.debugName = "LF.zero"; + this.forceInline = forceInline; assert(nameRefsAreLegal()); assert(isEmpty()); assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature(); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java index e72a07a2aff..17ba24019b8 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java @@ -1438,10 +1438,9 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); /*non-public*/ void updateForm(LambdaForm newForm) { if (form == newForm) return; - assert(this instanceof DirectMethodHandle && this.internalMemberName().isStatic()); - // ISSUE: Should we have a memory fence here? + newForm.prepare(); // as in MethodHandle. UNSAFE.putObject(this, FORM_OFFSET, newForm); - this.form.prepare(); // as in MethodHandle. + UNSAFE.fullFence(); } private static final long FORM_OFFSET; diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java index 934aab15996..015ea205f60 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -30,6 +30,7 @@ import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.function.Function; import sun.invoke.empty.Empty; import sun.invoke.util.ValueConversions; @@ -713,10 +714,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; LambdaForm form = makeGuardWithTestForm(basicType); BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL(); BoundMethodHandle mh; + try { mh = (BoundMethodHandle) data.constructor().invokeBasic(type, form, - (Object) test, (Object) target, (Object) fallback); + (Object) test, (Object) profile(target), (Object) profile(fallback)); } catch (Throwable ex) { throw uncaughtException(ex); } @@ -724,6 +726,129 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; return mh; } + + static + MethodHandle profile(MethodHandle target) { + if (DONT_INLINE_THRESHOLD >= 0) { + return makeBlockInlningWrapper(target); + } else { + return target; + } + } + + /** + * Block inlining during JIT-compilation of a target method handle if it hasn't been invoked enough times. + * Corresponding LambdaForm has @DontInline when compiled into bytecode. + */ + static + MethodHandle makeBlockInlningWrapper(MethodHandle target) { + LambdaForm lform = PRODUCE_BLOCK_INLINING_FORM.apply(target); + return new CountingWrapper(target, lform, + PRODUCE_BLOCK_INLINING_FORM, PRODUCE_REINVOKER_FORM, + DONT_INLINE_THRESHOLD); + } + + /** Constructs reinvoker lambda form which block inlining during JIT-compilation for a particular method handle */ + private static final Function PRODUCE_BLOCK_INLINING_FORM = new Function() { + @Override + public LambdaForm apply(MethodHandle target) { + return DelegatingMethodHandle.makeReinvokerForm(target, + MethodTypeForm.LF_DELEGATE_BLOCK_INLINING, CountingWrapper.class, "reinvoker.dontInline", false, + DelegatingMethodHandle.NF_getTarget, CountingWrapper.NF_maybeStopCounting); + } + }; + + /** Constructs simple reinvoker lambda form for a particular method handle */ + private static final Function PRODUCE_REINVOKER_FORM = new Function() { + @Override + public LambdaForm apply(MethodHandle target) { + return DelegatingMethodHandle.makeReinvokerForm(target, + MethodTypeForm.LF_DELEGATE, DelegatingMethodHandle.class, DelegatingMethodHandle.NF_getTarget); + } + }; + + /** + * Counting method handle. It has 2 states: counting and non-counting. + * It is in counting state for the first n invocations and then transitions to non-counting state. + * Behavior in counting and non-counting states is determined by lambda forms produced by + * countingFormProducer & nonCountingFormProducer respectively. + */ + static class CountingWrapper extends DelegatingMethodHandle { + private final MethodHandle target; + private int count; + private Function countingFormProducer; + private Function nonCountingFormProducer; + private volatile boolean isCounting; + + private CountingWrapper(MethodHandle target, LambdaForm lform, + Function countingFromProducer, + Function nonCountingFormProducer, + int count) { + super(target.type(), lform); + this.target = target; + this.count = count; + this.countingFormProducer = countingFromProducer; + this.nonCountingFormProducer = nonCountingFormProducer; + this.isCounting = (count > 0); + } + + @Hidden + @Override + protected MethodHandle getTarget() { + return target; + } + + @Override + public MethodHandle asTypeUncached(MethodType newType) { + MethodHandle newTarget = target.asType(newType); + MethodHandle wrapper; + if (isCounting) { + LambdaForm lform; + lform = countingFormProducer.apply(target); + wrapper = new CountingWrapper(newTarget, lform, countingFormProducer, nonCountingFormProducer, DONT_INLINE_THRESHOLD); + } else { + wrapper = newTarget; // no need for a counting wrapper anymore + } + return (asTypeCache = wrapper); + } + + boolean countDown() { + if (count <= 0) { + // Try to limit number of updates. MethodHandle.updateForm() doesn't guarantee LF update visibility. + if (isCounting) { + isCounting = false; + return true; + } else { + return false; + } + } else { + --count; + return false; + } + } + + @Hidden + static void maybeStopCounting(Object o1) { + CountingWrapper wrapper = (CountingWrapper) o1; + if (wrapper.countDown()) { + // Reached invocation threshold. Replace counting behavior with a non-counting one. + LambdaForm lform = wrapper.nonCountingFormProducer.apply(wrapper.target); + lform.compileToBytecode(); // speed up warmup by avoiding LF interpretation again after transition + wrapper.updateForm(lform); + } + } + + static final NamedFunction NF_maybeStopCounting; + static { + Class THIS_CLASS = CountingWrapper.class; + try { + NF_maybeStopCounting = new NamedFunction(THIS_CLASS.getDeclaredMethod("maybeStopCounting", Object.class)); + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); + } + } + } + static LambdaForm makeGuardWithTestForm(MethodType basicType) { LambdaForm lform = basicType.form().cachedLambdaForm(MethodTypeForm.LF_GWT); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java index c3d9ac12c09..1bd43538a91 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java @@ -47,10 +47,11 @@ import sun.misc.Unsafe; static final boolean TRACE_METHOD_LINKAGE; static final boolean USE_LAMBDA_FORM_EDITOR; static final int COMPILE_THRESHOLD; + static final int DONT_INLINE_THRESHOLD; static final int PROFILE_LEVEL; static { - final Object[] values = { false, false, false, false, false, null, null }; + final Object[] values = new Object[8]; AccessController.doPrivileged(new PrivilegedAction() { public Void run() { values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES"); @@ -59,7 +60,8 @@ import sun.misc.Unsafe; values[3] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE"); values[4] = Boolean.getBoolean("java.lang.invoke.MethodHandle.USE_LF_EDITOR"); values[5] = Integer.getInteger("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", 30); - values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0); + values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", 30); + values[7] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0); return null; } }); @@ -69,7 +71,8 @@ import sun.misc.Unsafe; TRACE_METHOD_LINKAGE = (Boolean) values[3]; USE_LAMBDA_FORM_EDITOR = (Boolean) values[4]; COMPILE_THRESHOLD = (Integer) values[5]; - PROFILE_LEVEL = (Integer) values[6]; + DONT_INLINE_THRESHOLD = (Integer) values[6]; + PROFILE_LEVEL = (Integer) values[7]; } /** Tell if any of the debugging switches are turned on. diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java index 43e85589410..6733e29ef93 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java @@ -63,24 +63,25 @@ final class MethodTypeForm { final @Stable LambdaForm[] lambdaForms; // Indexes into lambdaForms: static final int - LF_INVVIRTUAL = 0, // DMH invokeVirtual - LF_INVSTATIC = 1, - LF_INVSPECIAL = 2, - LF_NEWINVSPECIAL = 3, - LF_INVINTERFACE = 4, - LF_INVSTATIC_INIT = 5, // DMH invokeStatic with barrier - LF_INTERPRET = 6, // LF interpreter - LF_REBIND = 7, // BoundMethodHandle - LF_DELEGATE = 8, // DelegatingMethodHandle - LF_EX_LINKER = 9, // invokeExact_MT (for invokehandle) - LF_EX_INVOKER = 10, // MHs.invokeExact - LF_GEN_LINKER = 11, // generic invoke_MT (for invokehandle) - LF_GEN_INVOKER = 12, // generic MHs.invoke - LF_CS_LINKER = 13, // linkToCallSite_CS - LF_MH_LINKER = 14, // linkToCallSite_MH - LF_GWC = 15, // guardWithCatch (catchException) - LF_GWT = 16, // guardWithTest - LF_LIMIT = 17; + LF_INVVIRTUAL = 0, // DMH invokeVirtual + LF_INVSTATIC = 1, + LF_INVSPECIAL = 2, + LF_NEWINVSPECIAL = 3, + LF_INVINTERFACE = 4, + LF_INVSTATIC_INIT = 5, // DMH invokeStatic with barrier + LF_INTERPRET = 6, // LF interpreter + LF_REBIND = 7, // BoundMethodHandle + LF_DELEGATE = 8, // DelegatingMethodHandle + LF_DELEGATE_BLOCK_INLINING = 9, // Counting DelegatingMethodHandle w/ @DontInline + LF_EX_LINKER = 10, // invokeExact_MT (for invokehandle) + LF_EX_INVOKER = 11, // MHs.invokeExact + LF_GEN_LINKER = 12, // generic invoke_MT (for invokehandle) + LF_GEN_INVOKER = 13, // generic MHs.invoke + LF_CS_LINKER = 14, // linkToCallSite_CS + LF_MH_LINKER = 15, // linkToCallSite_MH + LF_GWC = 16, // guardWithCatch (catchException) + LF_GWT = 17, // guardWithTest + LF_LIMIT = 18; /** Return the type corresponding uniquely (1-1) to this MT-form. * It might have any primitive returns or arguments, but will have no references except Object. From 8bd23f1681aa417a2602cc093f7e39c470653c15 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 29 Oct 2014 17:25:23 -0700 Subject: [PATCH 49/67] 8062348: langtools tests should close file manager (group 1) Reviewed-by: darcy --- langtools/test/tools/all/RunCodingRules.java | 65 ++++----- .../test/tools/javac/6341866/T6341866.java | 87 ++++++------ .../test/tools/javac/6400872/T6400872.java | 7 +- .../test/tools/javac/6402516/Checker.java | 33 ++--- .../test/tools/javac/6440583/T6440583.java | 43 +++--- langtools/test/tools/javac/6902720/Test.java | 61 ++++---- .../test/tools/javac/7003595/T7003595.java | 30 ++-- .../javac/7079713/TestCircularClassfile.java | 17 +-- .../test/tools/javac/7142086/T7142086.java | 11 +- .../test/tools/javac/NoStringToLower.java | 49 +++---- .../Paths/6638501/JarFromManifestFailure.java | 39 ++--- .../Paths/TestCompileJARInClassPath.java | 17 +-- langtools/test/tools/javac/T6265400.java | 11 +- langtools/test/tools/javac/T6340549.java | 15 +- langtools/test/tools/javac/T6351767.java | 84 +++++------ langtools/test/tools/javac/T6361619.java | 21 +-- langtools/test/tools/javac/T6395974.java | 29 ++-- langtools/test/tools/javac/T6397044.java | 19 +-- langtools/test/tools/javac/T6397286.java | 45 +++--- langtools/test/tools/javac/T6403466.java | 31 ++-- langtools/test/tools/javac/T6406771.java | 15 +- langtools/test/tools/javac/T6407066.java | 25 ++-- langtools/test/tools/javac/T6410706.java | 29 ++-- .../test/tools/javac/T6458823/T6458823.java | 53 +++---- langtools/test/tools/javac/T6665791.java | 45 +++--- langtools/test/tools/javac/T6705935.java | 71 +++++----- langtools/test/tools/javac/T6900149.java | 19 +-- .../test/tools/javac/T6956462/T6956462.java | 19 +-- langtools/test/tools/javac/T6956638.java | 47 ++++--- langtools/test/tools/javac/T7142672/Bug.java | 39 ++--- langtools/test/tools/javac/T7159016.java | 15 +- .../T8003967/DetectMutableStaticFields.java | 25 ++-- ...rNamesAreNotCopiedToAnonymousInitTest.java | 105 +++++++------- .../InterruptedExceptionTest.java | 21 +-- .../TryWithResources/UnusedResourcesTest.java | 26 ++-- .../8022765/VerifyAnnotationsAttributed.java | 65 ++++----- .../repeatingAnnotations/combo/Helper.java | 44 +++--- .../api/AnnotatedArrayOrder.java | 24 ++-- .../api/ArrayCreationTree.java | 24 ++-- .../api/ArrayPositionConsistency.java | 24 ++-- .../failures/CheckErrorsForSource7.java | 133 +++++++++--------- .../tools/javac/api/6420409/T6420409.java | 33 ++--- .../tools/javac/api/6420464/T6420464.java | 23 +-- .../tools/javac/api/6431435/T6431435.java | 27 ++-- .../tools/javac/api/7086261/T7086261.java | 11 +- .../test/tools/javac/api/8007344/Test.java | 17 +-- langtools/test/tools/javac/api/Sibling.java | 27 ++-- langtools/test/tools/javac/api/T6258271.java | 13 +- langtools/test/tools/javac/api/T6265137.java | 16 ++- langtools/test/tools/javac/api/T6306137.java | 16 ++- langtools/test/tools/javac/api/T6345974.java | 23 +-- langtools/test/tools/javac/api/T6357331.java | 59 ++++---- langtools/test/tools/javac/api/T6358786.java | 23 +-- langtools/test/tools/javac/api/T6358955.java | 53 +++---- langtools/test/tools/javac/api/T6392782.java | 29 ++-- langtools/test/tools/javac/api/T6397104.java | 19 ++- langtools/test/tools/javac/api/T6400205.java | 28 ++-- langtools/test/tools/javac/api/T6400207.java | 45 +++--- langtools/test/tools/javac/api/T6412669.java | 35 ++--- langtools/test/tools/javac/api/T6419926.java | 23 +-- langtools/test/tools/javac/api/T6430241.java | 25 ++-- langtools/test/tools/javac/api/T6431879.java | 24 ++-- langtools/test/tools/javac/api/T6483788.java | 19 +-- langtools/test/tools/javac/api/T6501502.java | 24 ++-- .../javac/api/TestClientCodeWrapper.java | 56 ++++---- .../test/tools/javac/api/TestDocComments.java | 30 ++-- .../javac/api/TestGetElementReference.java | 41 +++--- .../test/tools/javac/api/TestGetScope.java | 24 ++-- .../test/tools/javac/api/TestJavacTask.java | 12 +- .../tools/javac/api/TestJavacTask_Lock.java | 17 ++- .../javac/api/TestJavacTask_Multiple.java | 21 +-- .../javac/api/TestJavacTask_ParseAttrGen.java | 17 ++- .../test/tools/javac/api/TestSearchPaths.java | 41 +++--- .../test/tools/javac/api/TestTreePath.java | 23 +-- langtools/test/tools/javac/api/TestTrees.java | 37 ++--- .../javac/api/taskListeners/CompileEvent.java | 23 +-- .../api/taskListeners/EventsBalancedTest.java | 7 +- .../taskListeners/TestSimpleAddRemove.java | 7 +- .../IntersectionTypeParserTest.java | 45 +++--- .../tools/javac/classreader/T7031108.java | 59 ++++---- .../defaultMethods/DefaultMethodFlags.java | 41 +++--- .../hiding/InterfaceMethodHidingTest.java | 25 ++-- .../syntax/TestDefaultMethodsSyntax.java | 19 +-- .../tools/javac/diags/CheckResourceKeys.java | 39 ++--- .../test/tools/javac/doclint/DocLintTest.java | 66 +++++---- .../javac/doctree/DocTreePathScannerTest.java | 25 ++-- .../doctree/SimpleDocTreeVisitorTest.java | 37 ++--- langtools/test/tools/javac/file/T7068451.java | 47 ++++--- .../test/tools/javac/flow/LVTHarness.java | 23 +-- .../javac/generics/bridges/BridgeHarness.java | 32 +++-- .../GenericConstructorAndDiamondTest.java | 24 ++-- .../generics/diamond/7030687/ParserTest.java | 33 ++--- .../generics/inference/7086601/T7086601b.java | 17 +-- .../tools/javac/lambda/BadLambdaExpr.java | 17 +-- .../test/tools/javac/lambda/TestSelfRef.java | 25 ++-- .../IntersectionTargetTypeTest.java | 11 +- .../SamConversionComboTest.java | 16 ++- .../org/openjdk/tests/javac/FDTest.java | 11 +- .../javac/nativeHeaders/NativeHeaderTest.java | 37 ++--- .../javac/options/xprefer/XPreferTest.java | 33 +++-- .../tools/javac/plugin/showtype/Test.java | 32 +++-- .../tools/javac/positions/TreeEndPosTest.java | 53 +++---- .../javac/processing/6348193/T6348193.java | 51 +++---- .../javac/processing/6348499/T6348499.java | 43 +++--- .../javac/processing/6378728/T6378728.java | 25 ++-- .../javac/processing/6414633/T6414633.java | 35 ++--- .../javac/processing/6430209/T6430209.java | 33 ++--- .../test/tools/javac/processing/T6439826.java | 39 ++--- .../processing/errors/TestSuppression.java | 65 ++++----- .../loader/testClose/TestClose.java | 79 ++++++----- .../model/testgetallmembers/Main.java | 103 +++++++------- .../processing/model/type/BoundsTest.java | 23 +-- .../type/IntersectionPropertiesTest.java | 12 +- .../elements/doccomments/TestDocComments.java | 11 +- .../doccomments/TestPackageInfoComments.java | 11 +- .../options/testCommandLineClasses/Test.java | 23 +-- .../rounds/BaseClassesNotReRead.java | 27 ++-- .../javac/profiles/ProfileOptionTest.java | 32 +++-- .../tools/javac/resolve/ResolveHarness.java | 18 ++- .../test/tools/javac/tree/ClassTreeTest.java | 39 ++--- .../javac/tree/DocCommentToplevelTest.java | 27 ++-- .../javac/tree/MissingSemicolonTest.java | 40 +++--- .../javac/tree/PrettySimpleStringTest.java | 39 ++--- langtools/test/tools/javac/tree/T6963934.java | 25 ++-- langtools/test/tools/javac/tree/T6993305.java | 21 +-- .../test/tools/javac/tree/TestToString.java | 16 ++- .../tools/javac/tree/TreePosRoundsTest.java | 30 ++-- .../test/tools/javac/tree/TreePosTest.java | 108 +++++++------- langtools/test/tools/javac/unit/T6198196.java | 35 +++-- .../tools/javac/varargs/6199075/T6199075.java | 26 ++-- .../tools/javac/varargs/7043922/T7043922.java | 28 ++-- .../test/tools/javac/versions/Versions.java | 31 ++-- .../test/tools/javadoc/CheckResourceKeys.java | 69 ++++----- .../javadoc/api/basic/DocletPathTest.java | 50 +++---- .../api/basic/GetTask_DiagListenerTest.java | 43 +++--- .../api/basic/GetTask_DocletClassTest.java | 60 ++++---- .../api/basic/GetTask_FileObjectsTest.java | 82 ++++++----- .../api/basic/GetTask_OptionsTest.java | 50 +++---- .../javadoc/api/basic/GetTask_WriterTest.java | 39 ++--- .../api/basic/JavadocTaskImplTest.java | 57 ++++---- .../javadoc/api/basic/TagletPathTest.java | 58 ++++---- .../javadoc/api/basic/Task_reuseTest.java | 23 +-- .../tools/javadoc/doclint/DocLintTest.java | 90 ++++++------ .../test/tools/javap/TestSuperclass.java | 21 +-- .../tools/sjavac/DependencyCollection.java | 99 ++++++------- 145 files changed, 2701 insertions(+), 2452 deletions(-) diff --git a/langtools/test/tools/all/RunCodingRules.java b/langtools/test/tools/all/RunCodingRules.java index 506dfc2bb15..a963f6b497e 100644 --- a/langtools/test/tools/all/RunCodingRules.java +++ b/langtools/test/tools/all/RunCodingRules.java @@ -77,41 +77,42 @@ public class RunCodingRules { } JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null); - DiagnosticListener noErrors = diagnostic -> { - Assert.check(diagnostic.getKind() != Diagnostic.Kind.ERROR, diagnostic.toString()); - }; + try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) { + DiagnosticListener noErrors = diagnostic -> { + Assert.check(diagnostic.getKind() != Diagnostic.Kind.ERROR, diagnostic.toString()); + }; - List crulesFiles = Files.walk(crulesDir) - .filter(entry -> entry.getFileName().toString().endsWith(".java")) - .filter(entry -> entry.getParent().endsWith("crules")) - .map(entry -> entry.toFile()) - .collect(Collectors.toList()); + List crulesFiles = Files.walk(crulesDir) + .filter(entry -> entry.getFileName().toString().endsWith(".java")) + .filter(entry -> entry.getParent().endsWith("crules")) + .map(entry -> entry.toFile()) + .collect(Collectors.toList()); - Path crulesTarget = targetDir.resolve("crules"); - Files.createDirectories(crulesTarget); - List crulesOptions = Arrays.asList("-d", crulesTarget.toString()); - javaCompiler.getTask(null, fm, noErrors, crulesOptions, null, - fm.getJavaFileObjectsFromFiles(crulesFiles)).call(); - Path registration = crulesTarget.resolve("META-INF/services/com.sun.source.util.Plugin"); - Files.createDirectories(registration.getParent()); - try (Writer metaInfServices = Files.newBufferedWriter(registration, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) { - metaInfServices.write("crules.CodingRulesAnalyzerPlugin\n"); + Path crulesTarget = targetDir.resolve("crules"); + Files.createDirectories(crulesTarget); + List crulesOptions = Arrays.asList("-d", crulesTarget.toString()); + javaCompiler.getTask(null, fm, noErrors, crulesOptions, null, + fm.getJavaFileObjectsFromFiles(crulesFiles)).call(); + Path registration = crulesTarget.resolve("META-INF/services/com.sun.source.util.Plugin"); + Files.createDirectories(registration.getParent()); + try (Writer metaInfServices = Files.newBufferedWriter(registration, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) { + metaInfServices.write("crules.CodingRulesAnalyzerPlugin\n"); + } + + List sources = sourceDirs.stream() + .flatMap(dir -> silentFilesWalk(dir)) + .filter(entry -> entry.getFileName().toString().endsWith(".java")) + .map(p -> p.toFile()) + .collect(Collectors.toList()); + + Path sourceTarget = targetDir.resolve("classes"); + Files.createDirectories(sourceTarget); + String processorPath = crulesTarget.toString() + File.pathSeparator + crulesDir.toString(); + List options = Arrays.asList("-d", sourceTarget.toString(), + "-processorpath", processorPath, "-Xplugin:coding_rules"); + javaCompiler.getTask(null, fm, noErrors, options, null, + fm.getJavaFileObjectsFromFiles(sources)).call(); } - - List sources = sourceDirs.stream() - .flatMap(dir -> silentFilesWalk(dir)) - .filter(entry -> entry.getFileName().toString().endsWith(".java")) - .map(p -> p.toFile()) - .collect(Collectors.toList()); - - Path sourceTarget = targetDir.resolve("classes"); - Files.createDirectories(sourceTarget); - String processorPath = crulesTarget.toString() + File.pathSeparator + crulesDir.toString(); - List options = Arrays.asList("-d", sourceTarget.toString(), - "-processorpath", processorPath, "-Xplugin:coding_rules"); - javaCompiler.getTask(null, fm, noErrors, options, null, - fm.getJavaFileObjectsFromFiles(sources)).call(); } Stream silentFilesWalk(Path dir) throws IllegalStateException { diff --git a/langtools/test/tools/javac/6341866/T6341866.java b/langtools/test/tools/javac/6341866/T6341866.java index 7c767206df3..5a3a596ed97 100644 --- a/langtools/test/tools/javac/6341866/T6341866.java +++ b/langtools/test/tools/javac/6341866/T6341866.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -113,58 +113,59 @@ public class T6341866 { JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); MyDiagListener dl = new MyDiagListener(); - StandardJavaFileManager fm = javac.getStandardFileManager(dl, null, null); + try (StandardJavaFileManager fm = javac.getStandardFileManager(dl, null, null)) { - // Note: class A references class B, so compile A if we want implicit compilation - File file = (implicitType != ImplicitType.NONE) ? a_java : b_java; - Iterable files = fm.getJavaFileObjects(file); + // Note: class A references class B, so compile A if we want implicit compilation + File file = (implicitType != ImplicitType.NONE) ? a_java : b_java; + Iterable files = fm.getJavaFileObjects(file); - //System.err.println("compile: " + opts + " " + files); + //System.err.println("compile: " + opts + " " + files); - boolean ok = javac.getTask(null, fm, dl, opts, null, files).call(); - if (!ok) { - error("compilation failed"); - return false; - } - - // check implicit compilation results if necessary - if (implicitType != ImplicitType.NONE) { - boolean expectClass = (implicitType != ImplicitType.OPT_NONE); - if (b_class.exists() != expectClass) { - if (b_class.exists()) - error("B implicitly compiled unexpectedly"); - else - error("B not impliictly compiled"); + boolean ok = javac.getTask(null, fm, dl, opts, null, files).call(); + if (!ok) { + error("compilation failed"); return false; } - } - // check message key results - String expectKey = null; - if (implicitType == ImplicitType.OPT_UNSET) { - switch (annoType) { - case SERVICE: - expectKey = "compiler.warn.proc.use.proc.or.implicit"; - break; - case SPECIFY: - expectKey = "compiler.warn.proc.use.implicit"; - break; + // check implicit compilation results if necessary + if (implicitType != ImplicitType.NONE) { + boolean expectClass = (implicitType != ImplicitType.OPT_NONE); + if (b_class.exists() != expectClass) { + if (b_class.exists()) + error("B implicitly compiled unexpectedly"); + else + error("B not impliictly compiled"); + return false; + } } - } - if (expectKey == null) { - if (dl.diagCodes.size() != 0) { - error("no diagnostics expected"); - return false; + // check message key results + String expectKey = null; + if (implicitType == ImplicitType.OPT_UNSET) { + switch (annoType) { + case SERVICE: + expectKey = "compiler.warn.proc.use.proc.or.implicit"; + break; + case SPECIFY: + expectKey = "compiler.warn.proc.use.implicit"; + break; + } } - } else { - if (!(dl.diagCodes.size() == 1 && dl.diagCodes.get(0).equals(expectKey))) { - error("unexpected diagnostics generated"); - return false; - } - } - return true; + if (expectKey == null) { + if (dl.diagCodes.size() != 0) { + error("no diagnostics expected"); + return false; + } + } else { + if (!(dl.diagCodes.size() == 1 && dl.diagCodes.get(0).equals(expectKey))) { + error("unexpected diagnostics generated"); + return false; + } + } + + return true; + } } static void createProcessorServices(String name) throws IOException { diff --git a/langtools/test/tools/javac/6400872/T6400872.java b/langtools/test/tools/javac/6400872/T6400872.java index 3849b295cad..318800f3ef8 100644 --- a/langtools/test/tools/javac/6400872/T6400872.java +++ b/langtools/test/tools/javac/6400872/T6400872.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -58,8 +58,7 @@ public class T6400872 { throws IOException { System.err.println("compile..."); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); - try { + try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { Iterable fileObjects = fm.getJavaFileObjectsFromFiles(Arrays.asList(files)); @@ -78,8 +77,6 @@ public class T6400872 { compiler.getTask(null, fm, null, options, null, fileObjects); if (!task.call()) throw new AssertionError("compilation failed"); - } finally { - fm.close(); } } diff --git a/langtools/test/tools/javac/6402516/Checker.java b/langtools/test/tools/javac/6402516/Checker.java index 34f9ead9e9a..2ab8694a138 100644 --- a/langtools/test/tools/javac/6402516/Checker.java +++ b/langtools/test/tools/javac/6402516/Checker.java @@ -54,25 +54,26 @@ abstract class Checker { }; JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); - Iterable files = - fm.getJavaFileObjectsFromFiles(getFiles(testSrc, fileNames)); - task = tool.getTask(null, fm, dl, null, null, files); - Iterable units = task.parse(); + try (StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null)) { + Iterable files = + fm.getJavaFileObjectsFromFiles(getFiles(testSrc, fileNames)); + task = tool.getTask(null, fm, dl, null, null, files); + Iterable units = task.parse(); - if (errors) - throw new AssertionError("errors occurred creating trees"); + if (errors) + throw new AssertionError("errors occurred creating trees"); - ScopeScanner s = new ScopeScanner(); - for (CompilationUnitTree unit: units) { - TreePath p = new TreePath(unit); - s.scan(p, getTrees()); - additionalChecks(getTrees(), unit); + ScopeScanner s = new ScopeScanner(); + for (CompilationUnitTree unit: units) { + TreePath p = new TreePath(unit); + s.scan(p, getTrees()); + additionalChecks(getTrees(), unit); + } + task = null; + + if (errors) + throw new AssertionError("errors occurred checking scopes"); } - task = null; - - if (errors) - throw new AssertionError("errors occurred checking scopes"); } // default impl: split ref at ";" and call checkLocal(scope, ref_segment) on scope and its enclosing scopes diff --git a/langtools/test/tools/javac/6440583/T6440583.java b/langtools/test/tools/javac/6440583/T6440583.java index 07997b140fe..7be04c6ab9c 100644 --- a/langtools/test/tools/javac/6440583/T6440583.java +++ b/langtools/test/tools/javac/6440583/T6440583.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -40,30 +40,31 @@ public class T6440583 { String testSrc = System.getProperty("test.src", "."); String testClasses = System.getProperty("test.classes", "."); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java"))); - JavacTask task = tool.getTask(null, fm, null, null, null, files); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java"))); + JavacTask task = tool.getTask(null, fm, null, null, null, files); - Iterable trees = task.parse(); + Iterable trees = task.parse(); - TreeScanner checker = new TreeScanner() { - public Boolean visitErroneous(ErroneousTree tree, Void ignore) { - JCErroneous etree = (JCErroneous) tree; - List errs = etree.getErrorTrees(); - System.err.println("errs: " + errs); - if (errs == null || errs.size() == 0) - throw new AssertionError("no error trees found"); - found = true; - return true; - } - }; + TreeScanner checker = new TreeScanner() { + public Boolean visitErroneous(ErroneousTree tree, Void ignore) { + JCErroneous etree = (JCErroneous) tree; + List errs = etree.getErrorTrees(); + System.err.println("errs: " + errs); + if (errs == null || errs.size() == 0) + throw new AssertionError("no error trees found"); + found = true; + return true; + } + }; - for (Tree tree: trees) - checker.scan(tree, null); + for (Tree tree: trees) + checker.scan(tree, null); - if (!found) - throw new AssertionError("no ErroneousTree nodes found"); + if (!found) + throw new AssertionError("no ErroneousTree nodes found"); + } } private static boolean found; diff --git a/langtools/test/tools/javac/6902720/Test.java b/langtools/test/tools/javac/6902720/Test.java index 1ae06898ed6..2d0d59c5915 100644 --- a/langtools/test/tools/javac/6902720/Test.java +++ b/langtools/test/tools/javac/6902720/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, 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,38 +54,39 @@ public class Test { void test(File test) throws Exception { JavacTool tool1 = JavacTool.create(); - StandardJavaFileManager fm = tool1.getStandardFileManager(null, null, null); - Iterable files = fm.getJavaFileObjects(test); + try (StandardJavaFileManager fm = tool1.getStandardFileManager(null, null, null)) { + Iterable files = fm.getJavaFileObjects(test); - // parse test file into a tree, and write it out to a stringbuffer using Pretty - JavacTask t1 = tool1.getTask(null, fm, null, null, null, files); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - Iterable trees = t1.parse(); - for (CompilationUnitTree tree: trees) { - new Pretty(pw, true).printExpr((JCTree) tree); - } - pw.close(); - - final String out = sw.toString(); - System.err.println("generated code:\n" + out + "\n"); - - // verify the generated code is valid Java by compiling it - JavacTool tool2 = JavacTool.create(); - JavaFileObject fo = new SimpleJavaFileObject(URI.create("output"), JavaFileObject.Kind.SOURCE) { - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) { - return out; + // parse test file into a tree, and write it out to a stringbuffer using Pretty + JavacTask t1 = tool1.getTask(null, fm, null, null, null, files); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + Iterable trees = t1.parse(); + for (CompilationUnitTree tree: trees) { + new Pretty(pw, true).printExpr((JCTree) tree); } - }; - JavacTask t2 = tool2.getTask(null, fm, null, null, null, Collections.singleton(fo)); - boolean ok = t2.call(); - if (!ok) - throw new Exception("compilation of generated code failed"); + pw.close(); - File expectedClass = new File(test.getName().replace(".java", ".class")); - if (!expectedClass.exists()) - throw new Exception(expectedClass + " not found"); + final String out = sw.toString(); + System.err.println("generated code:\n" + out + "\n"); + + // verify the generated code is valid Java by compiling it + JavacTool tool2 = JavacTool.create(); + JavaFileObject fo = new SimpleJavaFileObject(URI.create("output"), JavaFileObject.Kind.SOURCE) { + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return out; + } + }; + JavacTask t2 = tool2.getTask(null, fm, null, null, null, Collections.singleton(fo)); + boolean ok = t2.call(); + if (!ok) + throw new Exception("compilation of generated code failed"); + + File expectedClass = new File(test.getName().replace(".java", ".class")); + if (!expectedClass.exists()) + throw new Exception(expectedClass + " not found"); + } } } diff --git a/langtools/test/tools/javac/7003595/T7003595.java b/langtools/test/tools/javac/7003595/T7003595.java index 6d86b786857..5a7b81c20a9 100644 --- a/langtools/test/tools/javac/7003595/T7003595.java +++ b/langtools/test/tools/javac/7003595/T7003595.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -49,9 +49,6 @@ public class T7003595 { /** global decls ***/ - // Create a single file manager and reuse it for each compile to save time. - static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null); - //statistics static int checkCount = 0; @@ -112,15 +109,18 @@ public class T7003595 { } public static void main(String... args) throws Exception { - for (ClassKind ck1 : ClassKind.values()) { - String cname1 = "C1"; - for (ClassKind ck2 : ClassKind.values()) { - if (!ck1.isAllowed(ck2)) continue; - String cname2 = "C2"; - for (ClassKind ck3 : ClassKind.values()) { - if (!ck2.isAllowed(ck3)) continue; - String cname3 = "C3"; - new T7003595(new ClassKind[] {ck1, ck2, ck3}, new String[] { cname1, cname2, cname3 }).compileAndCheck(); + // Create a single file manager and reuse it for each compile to save time. + try (StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null)) { + for (ClassKind ck1 : ClassKind.values()) { + String cname1 = "C1"; + for (ClassKind ck2 : ClassKind.values()) { + if (!ck1.isAllowed(ck2)) continue; + String cname2 = "C2"; + for (ClassKind ck3 : ClassKind.values()) { + if (!ck2.isAllowed(ck3)) continue; + String cname3 = "C3"; + new T7003595(fm, new ClassKind[] {ck1, ck2, ck3}, new String[] { cname1, cname2, cname3 }).compileAndCheck(); + } } } } @@ -132,8 +132,10 @@ public class T7003595 { ClassKind[] cks; String[] cnames; + StandardJavaFileManager fm; - T7003595(ClassKind[] cks, String[] cnames) { + T7003595(StandardJavaFileManager fm, ClassKind[] cks, String[] cnames) { + this.fm = fm; this.cks = cks; this.cnames = cnames; } diff --git a/langtools/test/tools/javac/7079713/TestCircularClassfile.java b/langtools/test/tools/javac/7079713/TestCircularClassfile.java index bfa62b434d6..1837121d14a 100644 --- a/langtools/test/tools/javac/7079713/TestCircularClassfile.java +++ b/langtools/test/tools/javac/7079713/TestCircularClassfile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -100,13 +100,14 @@ public class TestCircularClassfile { public static void main(String... args) throws Exception { JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); - int count = 0; - for (SourceKind sk1 : SourceKind.values()) { - for (SourceKind sk2 : SourceKind.values()) { - for (TestKind tk : TestKind.values()) { - for (ClientKind ck : ClientKind.values()) { - new TestCircularClassfile("sub_"+count++, sk1, sk2, tk, ck).check(comp, fm); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { + int count = 0; + for (SourceKind sk1 : SourceKind.values()) { + for (SourceKind sk2 : SourceKind.values()) { + for (TestKind tk : TestKind.values()) { + for (ClientKind ck : ClientKind.values()) { + new TestCircularClassfile("sub_"+count++, sk1, sk2, tk, ck).check(comp, fm); + } } } } diff --git a/langtools/test/tools/javac/7142086/T7142086.java b/langtools/test/tools/javac/7142086/T7142086.java index 020d1135f13..6f99719823a 100644 --- a/langtools/test/tools/javac/7142086/T7142086.java +++ b/langtools/test/tools/javac/7142086/T7142086.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -96,10 +96,11 @@ public class T7142086 { void run(List sources) throws Exception { DiagnosticChecker dc = new DiagnosticChecker(); JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); - JavacTask ct = (JavacTask)comp.getTask(null, fm, dc, - null, null, sources); - ct.analyze(); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { + JavacTask ct = (JavacTask)comp.getTask(null, fm, dc, + null, null, sources); + ct.analyze(); + } } static class DiagnosticChecker implements javax.tools.DiagnosticListener { diff --git a/langtools/test/tools/javac/NoStringToLower.java b/langtools/test/tools/javac/NoStringToLower.java index b6a32900660..ca0255bafd1 100644 --- a/langtools/test/tools/javac/NoStringToLower.java +++ b/langtools/test/tools/javac/NoStringToLower.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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,31 +54,32 @@ public class NoStringToLower { */ boolean run(String... args) throws Exception { JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - JavaFileManager fm = c.getStandardFileManager(null, null, null); - JavaFileManager.Location javacLoc = findJavacLocation(fm); - String[] pkgs = { - "javax.annotation.processing", - "javax.lang.model", - "javax.tools", - "com.sun.source", - "com.sun.tools.classfile", - "com.sun.tools.doclet", - "com.sun.tools.doclint", - "com.sun.tools.javac", - "com.sun.tools.javadoc", - "com.sun.tools.javah", - "com.sun.tools.javap", - "com.sun.tools.jdeps", - "com.sun.tools.sjavac" - }; - for (String pkg: pkgs) { - for (JavaFileObject fo: fm.list(javacLoc, - pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) { - scan(fo); + try (JavaFileManager fm = c.getStandardFileManager(null, null, null)) { + JavaFileManager.Location javacLoc = findJavacLocation(fm); + String[] pkgs = { + "javax.annotation.processing", + "javax.lang.model", + "javax.tools", + "com.sun.source", + "com.sun.tools.classfile", + "com.sun.tools.doclet", + "com.sun.tools.doclint", + "com.sun.tools.javac", + "com.sun.tools.javadoc", + "com.sun.tools.javah", + "com.sun.tools.javap", + "com.sun.tools.jdeps", + "com.sun.tools.sjavac" + }; + for (String pkg: pkgs) { + for (JavaFileObject fo: fm.list(javacLoc, + pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) { + scan(fo); + } } - } - return (errors == 0); + return (errors == 0); + } } // depending on how the test is run, javac may be on bootclasspath or classpath diff --git a/langtools/test/tools/javac/Paths/6638501/JarFromManifestFailure.java b/langtools/test/tools/javac/Paths/6638501/JarFromManifestFailure.java index 20916d0680b..ef32c80d5b5 100644 --- a/langtools/test/tools/javac/Paths/6638501/JarFromManifestFailure.java +++ b/langtools/test/tools/javac/Paths/6638501/JarFromManifestFailure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, 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 @@ -71,28 +71,29 @@ public class JarFromManifestFailure { } } - static void compile(File classOutDir, Iterable classPath, File... files) { + static void compile(File classOutDir, Iterable classPath, File... files) throws IOException { System.err.println("compile..."); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); - Iterable fileObjects = - fm.getJavaFileObjectsFromFiles(Arrays.asList(files)); + try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { + Iterable fileObjects = + fm.getJavaFileObjectsFromFiles(Arrays.asList(files)); - List options = new ArrayList(); - if (classOutDir != null) { - options.add("-d"); - options.add(classOutDir.getPath()); - } - if (classPath != null) { - options.add("-classpath"); - options.add(join(classPath, File.pathSeparator)); - } - options.add("-verbose"); + List options = new ArrayList(); + if (classOutDir != null) { + options.add("-d"); + options.add(classOutDir.getPath()); + } + if (classPath != null) { + options.add("-classpath"); + options.add(join(classPath, File.pathSeparator)); + } + options.add("-verbose"); - JavaCompiler.CompilationTask task = - compiler.getTask(null, fm, null, options, null, fileObjects); - if (!task.call()) - throw new AssertionError("compilation failed"); + JavaCompiler.CompilationTask task = + compiler.getTask(null, fm, null, options, null, fileObjects); + if (!task.call()) + throw new AssertionError("compilation failed"); + } } static void jar(File jar, Iterable classPath, File base, File... files) diff --git a/langtools/test/tools/javac/Paths/TestCompileJARInClassPath.java b/langtools/test/tools/javac/Paths/TestCompileJARInClassPath.java index 96347c2ac31..13f8a1d8476 100644 --- a/langtools/test/tools/javac/Paths/TestCompileJARInClassPath.java +++ b/langtools/test/tools/javac/Paths/TestCompileJARInClassPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, 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 @@ -116,17 +116,18 @@ public class TestCompileJARInClassPath { javax.tools.JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); DiagnosticCollector diagnostics = new DiagnosticCollector<>(); - StandardJavaFileManager stdFileManager = javac.getStandardFileManager(diagnostics, null, null); + try (StandardJavaFileManager stdFileManager = javac.getStandardFileManager(diagnostics, null, null)) { - List files = new ArrayList<>(); - files.add(clientJarFile); + List files = new ArrayList<>(); + files.add(clientJarFile); - stdFileManager.setLocation(StandardLocation.CLASS_PATH, files); + stdFileManager.setLocation(StandardLocation.CLASS_PATH, files); - Iterable sourceFiles = stdFileManager.getJavaFileObjects(sourceFileToCompile); + Iterable sourceFiles = stdFileManager.getJavaFileObjects(sourceFileToCompile); - if (!javac.getTask(null, stdFileManager, diagnostics, null, null, sourceFiles).call()) { - throw new AssertionError("compilation failed"); + if (!javac.getTask(null, stdFileManager, diagnostics, null, null, sourceFiles).call()) { + throw new AssertionError("compilation failed"); + } } } } diff --git a/langtools/test/tools/javac/T6265400.java b/langtools/test/tools/javac/T6265400.java index 946b60ca5df..116f8f2e428 100644 --- a/langtools/test/tools/javac/T6265400.java +++ b/langtools/test/tools/javac/T6265400.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ -44,10 +44,11 @@ public class T6265400 { throw new NullPointerException(SILLY_BILLY); } }; - StandardJavaFileManager fm = javac.getStandardFileManager(dl, null, null); - Iterable files = - fm.getJavaFileObjectsFromStrings(Arrays.asList("badfile.java")); - javac.getTask(null, fm, dl, null, null, files).call(); + try (StandardJavaFileManager fm = javac.getStandardFileManager(dl, null, null)) { + Iterable files = + fm.getJavaFileObjectsFromStrings(Arrays.asList("badfile.java")); + javac.getTask(null, fm, dl, null, null, files).call(); + } } catch (RuntimeException e) { Throwable cause = e.getCause(); diff --git a/langtools/test/tools/javac/T6340549.java b/langtools/test/tools/javac/T6340549.java index 4b366e10f93..c24c80e3c14 100644 --- a/langtools/test/tools/javac/T6340549.java +++ b/langtools/test/tools/javac/T6340549.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ -44,13 +44,14 @@ public class T6340549 { try { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null); - jfm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(new File("."))); + try (StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null)) { + jfm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(new File("."))); - for (JavaFileObject jfo : jfm.list(StandardLocation.CLASS_PATH, - "", EnumSet.of(Kind.OTHER), false)) { - if (new File(jfo.getName()).isDirectory()) { - throw new AssertionError("Found directory: " + jfo); + for (JavaFileObject jfo : jfm.list(StandardLocation.CLASS_PATH, + "", EnumSet.of(Kind.OTHER), false)) { + if (new File(jfo.getName()).isDirectory()) { + throw new AssertionError("Found directory: " + jfo); + } } } } finally { diff --git a/langtools/test/tools/javac/T6351767.java b/langtools/test/tools/javac/T6351767.java index 9655844606b..bf3e412fb59 100644 --- a/langtools/test/tools/javac/T6351767.java +++ b/langtools/test/tools/javac/T6351767.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -38,52 +38,52 @@ public class T6351767 { public static void main(String... args) throws Exception { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - JavaFileManager jfm = compiler.getStandardFileManager(null, null, null); + try (JavaFileManager jfm = compiler.getStandardFileManager(null, null, null)) { - // test null - try { - jfm.list(StandardLocation.SOURCE_PATH, null, EnumSet.of(Kind.SOURCE), false); - error("NPE not thrown"); - } - catch (NullPointerException e) { - // expected - } + // test null + try { + jfm.list(StandardLocation.SOURCE_PATH, null, EnumSet.of(Kind.SOURCE), false); + error("NPE not thrown"); + } + catch (NullPointerException e) { + // expected + } - // test null fileKinds - try { - jfm.list(StandardLocation.SOURCE_PATH, "", null, false); - error("NPE not thrown"); - } - catch (NullPointerException e) { - // expected - } + // test null fileKinds + try { + jfm.list(StandardLocation.SOURCE_PATH, "", null, false); + error("NPE not thrown"); + } + catch (NullPointerException e) { + // expected + } - // test good package - boolean found = false; - for (JavaFileObject jfo : jfm.list(StandardLocation.PLATFORM_CLASS_PATH, - "java.lang", - EnumSet.of(Kind.CLASS), - false)) { - System.err.println("found " + jfo.toUri()); - if (jfo.isNameCompatible("Object", Kind.CLASS)) - found = true; - } - if (!found) - error("expected file, java/lang/Object.class, not found"); + // test good package + boolean found = false; + for (JavaFileObject jfo : jfm.list(StandardLocation.PLATFORM_CLASS_PATH, + "java.lang", + EnumSet.of(Kind.CLASS), + false)) { + System.err.println("found " + jfo.toUri()); + if (jfo.isNameCompatible("Object", Kind.CLASS)) + found = true; + } + if (!found) + error("expected file, java/lang/Object.class, not found"); - found = false; - // test good package (VM name) - for (JavaFileObject jfo : jfm.list(StandardLocation.PLATFORM_CLASS_PATH, - "java/lang", - EnumSet.of(Kind.CLASS), - false)) { - System.err.println("found " + jfo.toUri()); - if (jfo.isNameCompatible("Object", Kind.CLASS)) - found = true; + found = false; + // test good package (VM name) + for (JavaFileObject jfo : jfm.list(StandardLocation.PLATFORM_CLASS_PATH, + "java/lang", + EnumSet.of(Kind.CLASS), + false)) { + System.err.println("found " + jfo.toUri()); + if (jfo.isNameCompatible("Object", Kind.CLASS)) + found = true; + } + if (!found) + error("expected file, java/lang/Object.class, not found"); } - if (!found) - error("expected file, java/lang/Object.class, not found"); - } static void error(String msg) { diff --git a/langtools/test/tools/javac/T6361619.java b/langtools/test/tools/javac/T6361619.java index 8c36130979d..e2b72c583ad 100644 --- a/langtools/test/tools/javac/T6361619.java +++ b/langtools/test/tools/javac/T6361619.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -57,17 +57,18 @@ public class T6361619 extends AbstractProcessor { } }; - StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); - Iterable f = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrcDir, - self + ".java"))); + try (StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null)) { + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrcDir, + self + ".java"))); - JavacTask task = tool.getTask(out, fm, dl, flags, null, f); - MyTaskListener tl = new MyTaskListener(task); - task.setTaskListener(tl); + JavacTask task = tool.getTask(out, fm, dl, flags, null, f); + MyTaskListener tl = new MyTaskListener(task); + task.setTaskListener(tl); - // should complete, without exceptions - task.call(); + // should complete, without exceptions + task.call(); + } } public boolean process(Set elems, RoundEnvironment renv) { diff --git a/langtools/test/tools/javac/T6395974.java b/langtools/test/tools/javac/T6395974.java index 98d5d6572d0..6c820cb40af 100644 --- a/langtools/test/tools/javac/T6395974.java +++ b/langtools/test/tools/javac/T6395974.java @@ -44,24 +44,25 @@ public class T6395974 { String testSrc = System.getProperty("test.src"); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - Iterable f = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, self + ".java"))); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, self + ".java"))); - PrintWriter out = new PrintWriter(System.err, true); + PrintWriter out = new PrintWriter(System.err, true); - JavacTaskImpl task = (JavacTaskImpl) tool.getTask(out, - fm, - null, - Arrays.asList("-processor", - "Foo.java"), - null, - f); + JavacTaskImpl task = (JavacTaskImpl) tool.getTask(out, + fm, + null, + Arrays.asList("-processor", + "Foo.java"), + null, + f); - MyTaskListener tl = new MyTaskListener(); - task.setTaskListener(tl); + MyTaskListener tl = new MyTaskListener(); + task.setTaskListener(tl); - task.call(); + task.call(); + } } static class MyTaskListener implements TaskListener { diff --git a/langtools/test/tools/javac/T6397044.java b/langtools/test/tools/javac/T6397044.java index 51e659e19c4..db7b3716fb0 100644 --- a/langtools/test/tools/javac/T6397044.java +++ b/langtools/test/tools/javac/T6397044.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -42,14 +42,15 @@ public abstract class T6397044 { String srcDir = System.getProperty("test.src", "."); String self = T6397044.class.getName(); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - Iterable files - = fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(srcDir, self + ".java"))); - JavacTask task = tool.getTask(null, fm, null, null, null, files); - Iterable trees = task.parse(); - Checker checker = new Checker(); - for (CompilationUnitTree tree: trees) - checker.check(tree); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + Iterable files + = fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(srcDir, self + ".java"))); + JavacTask task = tool.getTask(null, fm, null, null, null, files); + Iterable trees = task.parse(); + Checker checker = new Checker(); + for (CompilationUnitTree tree: trees) + checker.check(tree); + } } public int x_public; diff --git a/langtools/test/tools/javac/T6397286.java b/langtools/test/tools/javac/T6397286.java index ec17d30298f..f19a0cbc067 100644 --- a/langtools/test/tools/javac/T6397286.java +++ b/langtools/test/tools/javac/T6397286.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -40,29 +40,30 @@ public class T6397286 { String self = T6397286.class.getName(); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrcDir, self + ".java"))); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrcDir, self + ".java"))); - JavacTask task = tool.getTask(null, fm, null, null, null, files); - task.setTaskListener(new TaskListener() { - public void started(TaskEvent e) { - throw new TaskEventError(e); - } - public void finished(TaskEvent e) { - } - }); + JavacTask task = tool.getTask(null, fm, null, null, null, files); + task.setTaskListener(new TaskListener() { + public void started(TaskEvent e) { + throw new TaskEventError(e); + } + public void finished(TaskEvent e) { + } + }); - try { - task.call(); - throw new AssertionError("no exception thrown"); - } catch (RuntimeException e) { - if (e.getCause() instanceof TaskEventError) { - TaskEventError tee = (TaskEventError) e.getCause(); - System.err.println("Exception thrown for " + tee.event + " as expected"); - } else { - e.printStackTrace(); - throw new AssertionError("TaskEventError not thrown"); + try { + task.call(); + throw new AssertionError("no exception thrown"); + } catch (RuntimeException e) { + if (e.getCause() instanceof TaskEventError) { + TaskEventError tee = (TaskEventError) e.getCause(); + System.err.println("Exception thrown for " + tee.event + " as expected"); + } else { + e.printStackTrace(); + throw new AssertionError("TaskEventError not thrown"); + } } } } diff --git a/langtools/test/tools/javac/T6403466.java b/langtools/test/tools/javac/T6403466.java index f6556fca2e3..e114231345d 100644 --- a/langtools/test/tools/javac/T6403466.java +++ b/langtools/test/tools/javac/T6403466.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -51,24 +51,25 @@ public class T6403466 extends AbstractProcessor { public static void main(String[] args) throws IOException { JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrcDir, self + ".java"))); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrcDir, self + ".java"))); - Iterable options = Arrays.asList("-processorpath", testClassDir, - "-processor", self, - "-s", ".", - "-d", "."); - JavacTask task = tool.getTask(out, fm, null, options, null, files); + Iterable options = Arrays.asList("-processorpath", testClassDir, + "-processor", self, + "-s", ".", + "-d", "."); + JavacTask task = tool.getTask(out, fm, null, options, null, files); - VerifyingTaskListener vtl = new VerifyingTaskListener(new File(testSrcDir, self + ".out")); - task.setTaskListener(vtl); + VerifyingTaskListener vtl = new VerifyingTaskListener(new File(testSrcDir, self + ".out")); + task.setTaskListener(vtl); - if (!task.call()) - throw new AssertionError("compilation failed"); + if (!task.call()) + throw new AssertionError("compilation failed"); - if (vtl.iter.hasNext() || vtl.errors) - throw new AssertionError("comparison against golden file failed."); + if (vtl.iter.hasNext() || vtl.errors) + throw new AssertionError("comparison against golden file failed."); + } } public boolean process(Set annos, RoundEnvironment rEnv) { diff --git a/langtools/test/tools/javac/T6406771.java b/langtools/test/tools/javac/T6406771.java index c41496d4f35..4f9be1e1a9f 100644 --- a/langtools/test/tools/javac/T6406771.java +++ b/langtools/test/tools/javac/T6406771.java @@ -33,21 +33,22 @@ public class T6406771 extends AbstractProcessor { // White-space after this point does not matter - public static void main(String[] args) { + public static void main(String[] args) throws IOException { String self = T6406771.class.getName(); String testSrc = System.getProperty("test.src"); String testClasses = System.getProperty("test.classes"); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - JavaFileObject f = fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, self+".java"))).iterator().next(); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + JavaFileObject f = fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, self+".java"))).iterator().next(); - List opts = Arrays.asList("-d", ".", "-processorpath", testClasses, "-processor", self, "-proc:only"); + List opts = Arrays.asList("-d", ".", "-processorpath", testClasses, "-processor", self, "-proc:only"); - JavacTask task = tool.getTask(null, fm, null, opts, null, Arrays.asList(f)); + JavacTask task = tool.getTask(null, fm, null, opts, null, Arrays.asList(f)); - if (!task.call()) - throw new AssertionError("failed"); + if (!task.call()) + throw new AssertionError("failed"); + } } public boolean process(Set elems, RoundEnvironment rEnv) { diff --git a/langtools/test/tools/javac/T6407066.java b/langtools/test/tools/javac/T6407066.java index 71897940179..058a270c30d 100644 --- a/langtools/test/tools/javac/T6407066.java +++ b/langtools/test/tools/javac/T6407066.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -37,20 +37,21 @@ public class T6407066 { String testClasses = System.getProperty("test.classes", "."); JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager jfm = tool.getStandardFileManager(null, null, null); + try (StandardJavaFileManager jfm = tool.getStandardFileManager(null, null, null)) { - List path = new ArrayList(); - path.add(new File("BadDirectory")); - path.add(new File(testSrc)); - path.add(new File("BadFile.jar")); + List path = new ArrayList(); + path.add(new File("BadDirectory")); + path.add(new File(testSrc)); + path.add(new File("BadFile.jar")); - jfm.setLocation(StandardLocation.SOURCE_PATH, path); + jfm.setLocation(StandardLocation.SOURCE_PATH, path); - List path2 = new ArrayList(); - for (File f: jfm.getLocation(StandardLocation.SOURCE_PATH)) - path2.add(f); + List path2 = new ArrayList(); + for (File f: jfm.getLocation(StandardLocation.SOURCE_PATH)) + path2.add(f); - if (!path.equals(path2)) - throw new AssertionError("path not preserved"); + if (!path.equals(path2)) + throw new AssertionError("path not preserved"); + } } } diff --git a/langtools/test/tools/javac/T6410706.java b/langtools/test/tools/javac/T6410706.java index 10b74cfc1b2..b62085545e5 100644 --- a/langtools/test/tools/javac/T6410706.java +++ b/langtools/test/tools/javac/T6410706.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -44,21 +44,22 @@ public class T6410706 { String testClasses = System.getProperty("test.classes", "."); JavacTool tool = JavacTool.create(); MyDiagListener dl = new MyDiagListener(); - StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); - fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(testClasses))); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6410706.class.getName()+".java"))); - JavacTask task = tool.getTask(null, fm, dl, null, null, files); - task.parse(); - task.analyze(); - task.generate(); + try (StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null)) { + fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(testClasses))); + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6410706.class.getName()+".java"))); + JavacTask task = tool.getTask(null, fm, dl, null, null, files); + task.parse(); + task.analyze(); + task.generate(); - // expect 2 notes: - // Note: T6410706.java uses or overrides a deprecated API. - // Note: Recompile with -Xlint:deprecation for details. + // expect 2 notes: + // Note: T6410706.java uses or overrides a deprecated API. + // Note: Recompile with -Xlint:deprecation for details. - if (dl.notes != 2) - throw new AssertionError(dl.notes + " notes given"); + if (dl.notes != 2) + throw new AssertionError(dl.notes + " notes given"); + } } private static class MyDiagListener implements DiagnosticListener diff --git a/langtools/test/tools/javac/T6458823/T6458823.java b/langtools/test/tools/javac/T6458823/T6458823.java index f02389dc304..9b48173ee9e 100644 --- a/langtools/test/tools/javac/T6458823/T6458823.java +++ b/langtools/test/tools/javac/T6458823/T6458823.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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,33 +55,34 @@ public class T6458823 { } DiagnosticCollector diagColl = new DiagnosticCollector(); - StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); - List options = new ArrayList(); - options.add("-processor"); - options.add("MyProcessor"); - options.add("-proc:only"); - List files = new ArrayList(); - files.add(new File(T6458823.class.getResource("TestClass.java").toURI())); - final CompilationTask task = compiler.getTask(null, fm, diagColl, - options, null, fm.getJavaFileObjectsFromFiles(files)); - task.call(); - int diagCount = 0; - for (Diagnostic diag : diagColl.getDiagnostics()) { - if (diag.getKind() != Diagnostic.Kind.WARNING) { - throw new AssertionError("Only warnings expected"); + try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { + List options = new ArrayList(); + options.add("-processor"); + options.add("MyProcessor"); + options.add("-proc:only"); + List files = new ArrayList(); + files.add(new File(T6458823.class.getResource("TestClass.java").toURI())); + final CompilationTask task = compiler.getTask(null, fm, diagColl, + options, null, fm.getJavaFileObjectsFromFiles(files)); + task.call(); + int diagCount = 0; + for (Diagnostic diag : diagColl.getDiagnostics()) { + if (diag.getKind() != Diagnostic.Kind.WARNING) { + throw new AssertionError("Only warnings expected"); + } + System.out.println(diag); + if (diag.getPosition() == Diagnostic.NOPOS) { + throw new AssertionError("No position info in message"); + } + if (diag.getSource() == null) { + throw new AssertionError("No source info in message"); + } + diagCount++; } - System.out.println(diag); - if (diag.getPosition() == Diagnostic.NOPOS) { - throw new AssertionError("No position info in message"); + if (diagCount != 2) { + throw new AssertionError("unexpected number of warnings: " + + diagCount + ", expected: 2"); } - if (diag.getSource() == null) { - throw new AssertionError("No source info in message"); - } - diagCount++; - } - if (diagCount != 2) { - throw new AssertionError("unexpected number of warnings: " + - diagCount + ", expected: 2"); } } } diff --git a/langtools/test/tools/javac/T6665791.java b/langtools/test/tools/javac/T6665791.java index 4430eb19fbd..af00fcdf683 100644 --- a/langtools/test/tools/javac/T6665791.java +++ b/langtools/test/tools/javac/T6665791.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -47,29 +47,30 @@ public class T6665791 { write(test_java, test); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager manager = - compiler.getStandardFileManager(null, null, null); - Iterable units = manager.getJavaFileObjects(test_java); - final StringWriter sw = new StringWriter(); - JavacTask task = (JavacTask) compiler.getTask(sw, manager, null, null, - null, units); + try (StandardJavaFileManager manager = + compiler.getStandardFileManager(null, null, null)) { + Iterable units = manager.getJavaFileObjects(test_java); + final StringWriter sw = new StringWriter(); + JavacTask task = (JavacTask) compiler.getTask(sw, manager, null, null, + null, units); - new TreeScanner() { - @Override - public Boolean visitClass(ClassTree arg0, Void arg1) { - sw.write(arg0.toString()); - return super.visitClass(arg0, arg1); + new TreeScanner() { + @Override + public Boolean visitClass(ClassTree arg0, Void arg1) { + sw.write(arg0.toString()); + return super.visitClass(arg0, arg1); + } + }.scan(task.parse(), null); + + System.out.println("output:"); + System.out.println(sw.toString()); + String found = sw.toString().replaceAll("\\s+", " ").trim(); + String expect = test.replaceAll("\\s+", " ").trim(); + if (!expect.equals(found)) { + System.out.println("expect: " + expect); + System.out.println("found: " + found); + throw new Exception("unexpected output"); } - }.scan(task.parse(), null); - - System.out.println("output:"); - System.out.println(sw.toString()); - String found = sw.toString().replaceAll("\\s+", " ").trim(); - String expect = test.replaceAll("\\s+", " ").trim(); - if (!expect.equals(found)) { - System.out.println("expect: " + expect); - System.out.println("found: " + found); - throw new Exception("unexpected output"); } } diff --git a/langtools/test/tools/javac/T6705935.java b/langtools/test/tools/javac/T6705935.java index 5cc770aece3..51e09177a12 100644 --- a/langtools/test/tools/javac/T6705935.java +++ b/langtools/test/tools/javac/T6705935.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2014, 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 @@ -45,46 +45,47 @@ public class T6705935 { java_home = java_home.getParentFile(); JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); - //System.err.println("platform class path: " + asList(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH))); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + //System.err.println("platform class path: " + asList(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH))); - for (JavaFileObject fo: fm.list(StandardLocation.PLATFORM_CLASS_PATH, - "java.lang", - Collections.singleton(JavaFileObject.Kind.CLASS), - false)) { - test++; + for (JavaFileObject fo: fm.list(StandardLocation.PLATFORM_CLASS_PATH, + "java.lang", + Collections.singleton(JavaFileObject.Kind.CLASS), + false)) { + test++; + + if (!(fo instanceof ZipFileObject || fo instanceof ZipFileIndexFileObject)) { + System.out.println("Skip " + fo.getClass().getSimpleName() + " " + fo.getName()); + skip++; + continue; + } + + //System.err.println(fo.getName()); + String p = fo.getName(); + int bra = p.indexOf("("); + int ket = p.indexOf(")"); + //System.err.println(bra + "," + ket + "," + p.length()); + if (bra == -1 || ket != p.length() -1) + throw new Exception("unexpected path: " + p + "[" + bra + "," + ket + "," + p.length()); + String part1 = p.substring(0, bra); + String part2 = p.substring(bra + 1, ket); + //System.err.println("[" + part1 + "|" + part2 + "]" + " " + java_home); + if (part1.equals(part2) || !part1.startsWith(java_home.getPath())) + throw new Exception("bad path: " + p); - if (!(fo instanceof ZipFileObject || fo instanceof ZipFileIndexFileObject)) { - System.out.println("Skip " + fo.getClass().getSimpleName() + " " + fo.getName()); - skip++; - continue; } - //System.err.println(fo.getName()); - String p = fo.getName(); - int bra = p.indexOf("("); - int ket = p.indexOf(")"); - //System.err.println(bra + "," + ket + "," + p.length()); - if (bra == -1 || ket != p.length() -1) - throw new Exception("unexpected path: " + p + "[" + bra + "," + ket + "," + p.length()); - String part1 = p.substring(0, bra); - String part2 = p.substring(bra + 1, ket); - //System.err.println("[" + part1 + "|" + part2 + "]" + " " + java_home); - if (part1.equals(part2) || !part1.startsWith(java_home.getPath())) - throw new Exception("bad path: " + p); + if (test == 0) + throw new Exception("no files found"); + if (skip == 0) + System.out.println(test + " files found"); + else + System.out.println(test + " files found, " + skip + " files skipped"); + + if (test == skip) + System.out.println("Warning: all files skipped; no platform classes found in zip files."); } - - if (test == 0) - throw new Exception("no files found"); - - if (skip == 0) - System.out.println(test + " files found"); - else - System.out.println(test + " files found, " + skip + " files skipped"); - - if (test == skip) - System.out.println("Warning: all files skipped; no platform classes found in zip files."); } private List asList(Iterable items) { diff --git a/langtools/test/tools/javac/T6900149.java b/langtools/test/tools/javac/T6900149.java index 151b39eeea1..5f3b3cf35a9 100644 --- a/langtools/test/tools/javac/T6900149.java +++ b/langtools/test/tools/javac/T6900149.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -37,14 +37,15 @@ public class T6900149 { DiagnosticCollector diag = new DiagnosticCollector(); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = - compiler.getStandardFileManager(null, null, null); - File emptyFile = createTempFile("Empty.java"); - File[] files = new File[] { emptyFile, emptyFile }; - CompilationTask task = compiler.getTask(null, fm, diag, - null, null, fm.getJavaFileObjects(files)); - if (! task.call()) { - throw new AssertionError("compilation failed"); + try (StandardJavaFileManager fm = + compiler.getStandardFileManager(null, null, null)) { + File emptyFile = createTempFile("Empty.java"); + File[] files = new File[] { emptyFile, emptyFile }; + CompilationTask task = compiler.getTask(null, fm, diag, + null, null, fm.getJavaFileObjects(files)); + if (! task.call()) { + throw new AssertionError("compilation failed"); + } } } diff --git a/langtools/test/tools/javac/T6956462/T6956462.java b/langtools/test/tools/javac/T6956462/T6956462.java index ef28b17c1a8..28c880929fd 100644 --- a/langtools/test/tools/javac/T6956462/T6956462.java +++ b/langtools/test/tools/javac/T6956462/T6956462.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -44,14 +44,15 @@ public class T6956462 { if (compiler == null) { throw new RuntimeException("can't get javax.tools.JavaCompiler!"); } - StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); - List files = new ArrayList(); - files.add(new File(T6956462.class.getResource("TestClass.java").toURI())); - final CompilationTask task = compiler.getTask(null, fm, null, - null, null, fm.getJavaFileObjectsFromFiles(files)); - JavacTask javacTask = (JavacTask) task; - for (CompilationUnitTree cu : javacTask.parse()) { - cu.accept(new MyVisitor(javacTask), null); + try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { + List files = new ArrayList(); + files.add(new File(T6956462.class.getResource("TestClass.java").toURI())); + final CompilationTask task = compiler.getTask(null, fm, null, + null, null, fm.getJavaFileObjectsFromFiles(files)); + JavacTask javacTask = (JavacTask) task; + for (CompilationUnitTree cu : javacTask.parse()) { + cu.accept(new MyVisitor(javacTask), null); + } } } diff --git a/langtools/test/tools/javac/T6956638.java b/langtools/test/tools/javac/T6956638.java index 98ed012dd4d..3d8a777ed05 100644 --- a/langtools/test/tools/javac/T6956638.java +++ b/langtools/test/tools/javac/T6956638.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -96,34 +96,35 @@ public class T6956638 { List compileOptions = Arrays.asList("-d", classesDir.getPath()); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); DiagnosticCollector diagnosticCollector = new DiagnosticCollector(); - StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnosticCollector, null, null); - Iterable sourceFileObjects = fileManager.getJavaFileObjects(sourceFiles); - System.err.println("1- javac given java source JavaFileObjects " + sourceFileObjects); - JavaCompiler.CompilationTask task = compiler.getTask(compilerOutputStream, fileManager, null, compileOptions, null, sourceFileObjects); - JavacTask javacTask = (JavacTask) task; + try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnosticCollector, null, null)) { + Iterable sourceFileObjects = fileManager.getJavaFileObjects(sourceFiles); + System.err.println("1- javac given java source JavaFileObjects " + sourceFileObjects); + JavaCompiler.CompilationTask task = compiler.getTask(compilerOutputStream, fileManager, null, compileOptions, null, sourceFileObjects); + JavacTask javacTask = (JavacTask) task; - Iterable parsedTrees = javacTask.parse(); - Iterable analyzedTrees = javacTask.analyze(); - Iterable generatedFiles = javacTask.generate(); + Iterable parsedTrees = javacTask.parse(); + Iterable analyzedTrees = javacTask.analyze(); + Iterable generatedFiles = javacTask.generate(); - System.err.println("2- parsed:" + size(parsedTrees) + " analysed:" + size(analyzedTrees) + " generated:" + size(generatedFiles)); + System.err.println("2- parsed:" + size(parsedTrees) + " analysed:" + size(analyzedTrees) + " generated:" + size(generatedFiles)); - System.err.print("3-"); - for (JavaFileObject f : generatedFiles) - System.err.print(" " + f); - System.err.println(""); + System.err.print("3-"); + for (JavaFileObject f : generatedFiles) + System.err.print(" " + f); + System.err.println(""); - System.err.print("5-"); - for (File f : classesDir.listFiles()) - System.err.print(" " + f); - System.err.println(""); + System.err.print("5-"); + for (File f : classesDir.listFiles()) + System.err.print(" " + f); + System.err.println(""); - System.err.println("----"); - System.err.println(compilerOutputStream.toString()); + System.err.println("----"); + System.err.println(compilerOutputStream.toString()); - if (size(generatedFiles) != size(parsedTrees)) { - throw new Exception("wrong number of files generated: " + size(generatedFiles) - + " expected: " + size(parsedTrees)); + if (size(generatedFiles) != size(parsedTrees)) { + throw new Exception("wrong number of files generated: " + size(generatedFiles) + + " expected: " + size(parsedTrees)); + } } } diff --git a/langtools/test/tools/javac/T7142672/Bug.java b/langtools/test/tools/javac/T7142672/Bug.java index 1bd28dc1808..efb14d7d156 100644 --- a/langtools/test/tools/javac/T7142672/Bug.java +++ b/langtools/test/tools/javac/T7142672/Bug.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -58,28 +58,29 @@ public class Bug { } }; - StandardJavaFileManager sjfm = javac.getStandardFileManager(dl,null,null); + try (StandardJavaFileManager sjfm = javac.getStandardFileManager(dl,null,null)) { - List opts = new ArrayList(); - opts.add("-proc:only"); - opts.add("-processor"); - opts.add("AnnoProcessor"); + List opts = new ArrayList(); + opts.add("-proc:only"); + opts.add("-processor"); + opts.add("AnnoProcessor"); - boolean xxx; + boolean xxx; - System.err.println("\n-- " + name); - task2 = javac.getTask(pw, sjfm, dl, opts, Arrays.asList(name), null); - xxx = task2.call(); + System.err.println("\n-- " + name); + task2 = javac.getTask(pw, sjfm, dl, opts, Arrays.asList(name), null); + xxx = task2.call(); - String out = sw.toString(); - System.err.println(out); - if (out.contains("Assert")) { - System.err.println("--Failed: Assertion failure"); - System.exit(1); - } - if (!out.contains(expectedMsg)) { - System.err.println("--Failed: Expected diagnostic not found"); - System.exit(1); + String out = sw.toString(); + System.err.println(out); + if (out.contains("Assert")) { + System.err.println("--Failed: Assertion failure"); + System.exit(1); + } + if (!out.contains(expectedMsg)) { + System.err.println("--Failed: Expected diagnostic not found"); + System.exit(1); + } } } } diff --git a/langtools/test/tools/javac/T7159016.java b/langtools/test/tools/javac/T7159016.java index 70df0f8e931..f8230177574 100644 --- a/langtools/test/tools/javac/T7159016.java +++ b/langtools/test/tools/javac/T7159016.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -45,6 +45,7 @@ import javax.lang.model.SourceVersion; import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic; import javax.tools.JavaCompiler; +import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; public class T7159016 { @@ -58,11 +59,13 @@ public class T7159016 { w.close(); } JavaCompiler jc = ToolProvider.getSystemJavaCompiler(); - JavaCompiler.CompilationTask task = jc.getTask(null, null, null, null, null, - jc.getStandardFileManager(null, null, null).getJavaFileObjects(src)); - task.setProcessors(Collections.singleton(new Proc())); - if (!task.call()) { - throw new Error("Test failed"); + try (StandardJavaFileManager fm = jc.getStandardFileManager(null, null, null)) { + JavaCompiler.CompilationTask task = jc.getTask(null, fm, null, null, null, + fm.getJavaFileObjects(src)); + task.setProcessors(Collections.singleton(new Proc())); + if (!task.call()) { + throw new Error("Test failed"); + } } } diff --git a/langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java b/langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java index c419cd3332e..5a880681d4a 100644 --- a/langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java +++ b/langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -179,18 +179,19 @@ public class DetectMutableStaticFields { ConstantPoolException, InvalidDescriptor { JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - JavaFileManager.Location location = - StandardLocation.locationFor(resource.getPath()); - fm.setLocation(location, com.sun.tools.javac.util.List.of( - new File(resource.getPath()))); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + JavaFileManager.Location location = + StandardLocation.locationFor(resource.getPath()); + fm.setLocation(location, com.sun.tools.javac.util.List.of( + new File(resource.getPath()))); - for (JavaFileObject file : fm.list(location, "", EnumSet.of(CLASS), true)) { - String className = fm.inferBinaryName(location, file); - int index = className.lastIndexOf('.'); - String pckName = index == -1 ? "" : className.substring(0, index); - if (shouldAnalyzePackage(pckName)) { - analyzeClassFile(ClassFile.read(file.openInputStream())); + for (JavaFileObject file : fm.list(location, "", EnumSet.of(CLASS), true)) { + String className = fm.inferBinaryName(location, file); + int index = className.lastIndexOf('.'); + String pckName = index == -1 ? "" : className.substring(0, index); + if (shouldAnalyzePackage(pckName)) { + analyzeClassFile(ClassFile.read(file.openInputStream())); + } } } } diff --git a/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java b/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java index f58d186ffb1..d11d3dd471f 100644 --- a/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java +++ b/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -132,73 +132,74 @@ public class ParameterNamesAreNotCopiedToAnonymousInitTest { throws IOException { Assert.checkNonNull(paramsToCheck, nonNullParamPositionsMsg); JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); - Iterable fos = - fm.getJavaFileObjectsFromFiles( - Arrays.asList(new File(System.getProperty("test.src"), - this.getClass().getName() + ".java"))); - JavacTask task = (JavacTask) c.getTask(null, fm, null, - Arrays.asList("-d", System.getProperty("user.dir")), null, fos); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + Iterable fos = + fm.getJavaFileObjectsFromFiles( + Arrays.asList(new File(System.getProperty("test.src"), + this.getClass().getName() + ".java"))); + JavacTask task = (JavacTask) c.getTask(null, fm, null, + Arrays.asList("-d", System.getProperty("user.dir")), null, fos); - BasicJavacTask impl = (BasicJavacTask)task; - Context context = impl.getContext(); - final Names names = Names.instance(context); + BasicJavacTask impl = (BasicJavacTask)task; + Context context = impl.getContext(); + final Names names = Names.instance(context); - task.addTaskListener(new TaskListener() { + task.addTaskListener(new TaskListener() { - @Override - public void started(TaskEvent e) {} + @Override + public void started(TaskEvent e) {} - @Override - public void finished(TaskEvent e) { - class TheTreeScanner extends TreeScanner { - boolean foundAndCorrect = false; + @Override + public void finished(TaskEvent e) { + class TheTreeScanner extends TreeScanner { + boolean foundAndCorrect = false; - @Override - public void visitMethodDef(JCTree.JCMethodDecl tree) { - ClassSymbol clazz = (ClassSymbol)tree.sym.owner; - if (clazz.owner.name.toString().equals(classOwnerName) && - tree.sym.name == names.init) { + @Override + public void visitMethodDef(JCTree.JCMethodDecl tree) { + ClassSymbol clazz = (ClassSymbol)tree.sym.owner; + if (clazz.owner.name.toString().equals(classOwnerName) && + tree.sym.name == names.init) { - int currentParamPos = 0; - int paramArrayIndex = 0; + int currentParamPos = 0; + int paramArrayIndex = 0; - List params = tree.sym.params; - while (params.nonEmpty() && paramArrayIndex < paramsToCheck.size()) { - VarSymbol param = params.head; - if (currentParamPos == paramsToCheck.get(paramArrayIndex)) { - if (!param.name.toString() - .equals(paramNames.get(paramArrayIndex))) { - error(paramNameNotCopiedAssertionMsg); + List params = tree.sym.params; + while (params.nonEmpty() && paramArrayIndex < paramsToCheck.size()) { + VarSymbol param = params.head; + if (currentParamPos == paramsToCheck.get(paramArrayIndex)) { + if (!param.name.toString() + .equals(paramNames.get(paramArrayIndex))) { + error(paramNameNotCopiedAssertionMsg); + } + paramArrayIndex++; } - paramArrayIndex++; + currentParamPos++; + params = params.tail; } - currentParamPos++; - params = params.tail; + foundAndCorrect = paramArrayIndex >= paramsToCheck.size(); } - foundAndCorrect = paramArrayIndex >= paramsToCheck.size(); + super.visitMethodDef(tree); } - super.visitMethodDef(tree); } - } - if (e.getKind() == TaskEvent.Kind.ANALYZE) { - CompilationUnitTree compUnitTree = e.getCompilationUnit(); - boolean foundAndCorrect = false; - for (Tree tree : compUnitTree.getTypeDecls()) { - TheTreeScanner scanner = new TheTreeScanner(); - scanner.scan((JCTree) tree); - foundAndCorrect = foundAndCorrect | scanner.foundAndCorrect; - } - if (!foundAndCorrect) { - error(seekMethodNotFound); + if (e.getKind() == TaskEvent.Kind.ANALYZE) { + CompilationUnitTree compUnitTree = e.getCompilationUnit(); + boolean foundAndCorrect = false; + for (Tree tree : compUnitTree.getTypeDecls()) { + TheTreeScanner scanner = new TheTreeScanner(); + scanner.scan((JCTree) tree); + foundAndCorrect = foundAndCorrect | scanner.foundAndCorrect; + } + if (!foundAndCorrect) { + error(seekMethodNotFound); + } } } + }); + + if (!task.call()) { + error(compilationFailed); } - }); - - if (!task.call()) { - error(compilationFailed); } } diff --git a/langtools/test/tools/javac/TryWithResources/InterruptedExceptionTest.java b/langtools/test/tools/javac/TryWithResources/InterruptedExceptionTest.java index 761a62972cf..eadadeb4ece 100644 --- a/langtools/test/tools/javac/TryWithResources/InterruptedExceptionTest.java +++ b/langtools/test/tools/javac/TryWithResources/InterruptedExceptionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -117,16 +117,17 @@ public class InterruptedExceptionTest { //create default shared JavaCompiler - reused across multiple compilations JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { - for (XlintOption xlint : XlintOption.values()) { - for (SuppressLevel suppress_decl : SuppressLevel.values()) { - for (SuppressLevel suppress_use : SuppressLevel.values()) { - for (ClassKind ck : ClassKind.values()) { - for (ExceptionKind ek_decl : ExceptionKind.values()) { - for (ExceptionKind ek_use : ExceptionKind.values()) { - new InterruptedExceptionTest(xlint, suppress_decl, - suppress_use, ck, ek_decl, ek_use).run(comp, fm); + for (XlintOption xlint : XlintOption.values()) { + for (SuppressLevel suppress_decl : SuppressLevel.values()) { + for (SuppressLevel suppress_use : SuppressLevel.values()) { + for (ClassKind ck : ClassKind.values()) { + for (ExceptionKind ek_decl : ExceptionKind.values()) { + for (ExceptionKind ek_use : ExceptionKind.values()) { + new InterruptedExceptionTest(xlint, suppress_decl, + suppress_use, ck, ek_decl, ek_use).run(comp, fm); + } } } } diff --git a/langtools/test/tools/javac/TryWithResources/UnusedResourcesTest.java b/langtools/test/tools/javac/TryWithResources/UnusedResourcesTest.java index 70d44e47962..3fa221a20cc 100644 --- a/langtools/test/tools/javac/TryWithResources/UnusedResourcesTest.java +++ b/langtools/test/tools/javac/TryWithResources/UnusedResourcesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -161,20 +161,24 @@ public class UnusedResourcesTest { } public static void main(String... args) throws Exception { - for (XlintOption xlint : XlintOption.values()) { - for (SuppressLevel suppressLevel : SuppressLevel.values()) { - for (ResourceUsage usage1 : ResourceUsage.values()) { - for (ResourceUsage usage2 : ResourceUsage.values()) { - for (ResourceUsage usage3 : ResourceUsage.values()) { - test(xlint, - suppressLevel, - usage1, - usage2, - usage3); + try { + for (XlintOption xlint : XlintOption.values()) { + for (SuppressLevel suppressLevel : SuppressLevel.values()) { + for (ResourceUsage usage1 : ResourceUsage.values()) { + for (ResourceUsage usage2 : ResourceUsage.values()) { + for (ResourceUsage usage3 : ResourceUsage.values()) { + test(xlint, + suppressLevel, + usage1, + usage2, + usage3); + } } } } } + } finally { + fm.close(); } } diff --git a/langtools/test/tools/javac/annotations/neg/8022765/VerifyAnnotationsAttributed.java b/langtools/test/tools/javac/annotations/neg/8022765/VerifyAnnotationsAttributed.java index 29029656a88..8d67b25503f 100644 --- a/langtools/test/tools/javac/annotations/neg/8022765/VerifyAnnotationsAttributed.java +++ b/langtools/test/tools/javac/annotations/neg/8022765/VerifyAnnotationsAttributed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -41,38 +41,39 @@ public class VerifyAnnotationsAttributed { File testSrc = new File(System.getProperty("test.src")); File testFile = new File(testSrc, args[0]); if (!testFile.canRead()) throw new IllegalStateException("Cannot read the test source"); - JavacFileManager fm = JavacTool.create().getStandardFileManager(null, null, null); - JavacTask task = JavacTool.create().getTask(null, - fm, - null, - Collections.emptyList(), - null, - fm.getJavaFileObjects(testFile)); - final Trees trees = Trees.instance(task); - final CompilationUnitTree cut = task.parse().iterator().next(); - task.analyze(); + try (JavacFileManager fm = JavacTool.create().getStandardFileManager(null, null, null)) { + JavacTask task = JavacTool.create().getTask(null, + fm, + null, + Collections.emptyList(), + null, + fm.getJavaFileObjects(testFile)); + final Trees trees = Trees.instance(task); + final CompilationUnitTree cut = task.parse().iterator().next(); + task.analyze(); - //ensure all the annotation attributes are annotated meaningfully - //all the attributes in the test file should contain either an identifier - //or a select, so only checking those for a reasonable Element/Symbol. - new TreePathScanner() { - @Override - public Void visitIdentifier(IdentifierTree node, Void p) { - verifyAttributedMeaningfully(); - return super.visitIdentifier(node, p); - } - @Override - public Void visitMemberSelect(MemberSelectTree node, Void p) { - verifyAttributedMeaningfully(); - return super.visitMemberSelect(node, p); - } - private void verifyAttributedMeaningfully() { - Element el = trees.getElement(getCurrentPath()); - - if (el == null || el.getKind() == ElementKind.OTHER) { - throw new IllegalStateException("Not attributed properly: " + getCurrentPath().getParentPath().getLeaf()); + //ensure all the annotation attributes are annotated meaningfully + //all the attributes in the test file should contain either an identifier + //or a select, so only checking those for a reasonable Element/Symbol. + new TreePathScanner() { + @Override + public Void visitIdentifier(IdentifierTree node, Void p) { + verifyAttributedMeaningfully(); + return super.visitIdentifier(node, p); } - } - }.scan(cut, null); + @Override + public Void visitMemberSelect(MemberSelectTree node, Void p) { + verifyAttributedMeaningfully(); + return super.visitMemberSelect(node, p); + } + private void verifyAttributedMeaningfully() { + Element el = trees.getElement(getCurrentPath()); + + if (el == null || el.getKind() == ElementKind.OTHER) { + throw new IllegalStateException("Not attributed properly: " + getCurrentPath().getParentPath().getLeaf()); + } + } + }.scan(cut, null); + } } } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java index 97bfdb355e9..642f434b606 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -102,29 +102,31 @@ public class Helper { throw new RuntimeException("can't get javax.tools.JavaCompiler!"); } - StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); - - // Assuming filesCount can maximum be 2 and if true, one file is package-info.java - if (isPkgInfoPresent(files)) { - JavacTask task = (JavacTask) compiler.getTask(null, fm, diagnostics, null, null, files); - try { - fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir)); - task.generate(); - } catch (IOException ioe) { - throw new RuntimeException("Compilation failed for package level tests", ioe); - } - int err = 0; - for (Diagnostic d : diagnostics.getDiagnostics()) { - if(d.getKind() == Diagnostic.Kind.ERROR) { - err++; + try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { + // Assuming filesCount can maximum be 2 and if true, one file is package-info.java + if (isPkgInfoPresent(files)) { + JavacTask task = (JavacTask) compiler.getTask(null, fm, diagnostics, null, null, files); + try { + fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir)); + task.generate(); + } catch (IOException ioe) { + throw new RuntimeException("Compilation failed for package level tests", ioe); } + int err = 0; + for (Diagnostic d : diagnostics.getDiagnostics()) { + if(d.getKind() == Diagnostic.Kind.ERROR) { + err++; + } + } + ok = (err == 0); + } else { + CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, files); + ok = task.call(); } - ok = (err == 0); - } else { - CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, files); - ok = task.call(); + return ok; + } catch (IOException e) { + throw new Error(e); } - return ok; } static private boolean isPkgInfoPresent(Iterable files) { diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java b/langtools/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java index f734e44b091..2c7ac550764 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -46,18 +46,18 @@ public class AnnotatedArrayOrder { public static void main(String[] args) throws Exception { PrintWriter out = new PrintWriter(System.out, true); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File testSrc = new File(System.getProperty("test.src")); - Iterable f = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "AnnotatedArrayOrder.java"))); - JavacTask task = tool.getTask(out, fm, null, null, null, f); - Iterable trees = task.parse(); - out.flush(); - - Scanner s = new Scanner(); - for (CompilationUnitTree t: trees) - s.scan(t, null); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File testSrc = new File(System.getProperty("test.src")); + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "AnnotatedArrayOrder.java"))); + JavacTask task = tool.getTask(out, fm, null, null, null, f); + Iterable trees = task.parse(); + out.flush(); + Scanner s = new Scanner(); + for (CompilationUnitTree t: trees) + s.scan(t, null); + } } private static class Scanner extends TreeScanner { diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java index 8f1a1ebdaac..f9028a56370 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -48,18 +48,18 @@ public class ArrayCreationTree { public static void main(String[] args) throws Exception { PrintWriter out = new PrintWriter(System.out, true); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File testSrc = new File(System.getProperty("test.src")); - Iterable f = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "ArrayCreationTree.java"))); - JavacTask task = tool.getTask(out, fm, null, null, null, f); - Iterable trees = task.parse(); - out.flush(); - - Scanner s = new Scanner(); - for (CompilationUnitTree t: trees) - s.scan(t, null); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File testSrc = new File(System.getProperty("test.src")); + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "ArrayCreationTree.java"))); + JavacTask task = tool.getTask(out, fm, null, null, null, f); + Iterable trees = task.parse(); + out.flush(); + Scanner s = new Scanner(); + for (CompilationUnitTree t: trees) + s.scan(t, null); + } } private static class Scanner extends TreeScanner { diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java index dc1b9b50517..f42b2a56258 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -47,18 +47,18 @@ public class ArrayPositionConsistency { public static void main(String[] args) throws Exception { PrintWriter out = new PrintWriter(System.out, true); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File testSrc = new File(System.getProperty("test.src")); - Iterable f = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "ArrayPositionConsistency.java"))); - JavacTask task = tool.getTask(out, fm, null, null, null, f); - Iterable trees = task.parse(); - out.flush(); - - Scanner s = new Scanner(); - for (CompilationUnitTree t: trees) - s.scan(t, null); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File testSrc = new File(System.getProperty("test.src")); + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "ArrayPositionConsistency.java"))); + JavacTask task = tool.getTask(out, fm, null, null, null, f); + Iterable trees = task.parse(); + out.flush(); + Scanner s = new Scanner(); + for (CompilationUnitTree t: trees) + s.scan(t, null); + } } private static class Scanner extends TreeScanner { diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CheckErrorsForSource7.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CheckErrorsForSource7.java index 56c8adf588e..6bf666550f6 100644 --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CheckErrorsForSource7.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CheckErrorsForSource7.java @@ -72,77 +72,78 @@ public class CheckErrorsForSource7 { File testSrc = new File(System.getProperty("test.src")); File testFile = new File(testSrc, args[0]); if (!testFile.canRead()) throw new IllegalStateException("Cannot read the test source"); - JavacFileManager fm = JavacTool.create().getStandardFileManager(null, null, null); + try (JavacFileManager fm = JavacTool.create().getStandardFileManager(null, null, null)) { - //gather spans of the @TA annotations into typeAnnotationSpans: - JavacTask task = JavacTool.create().getTask(null, - fm, - null, - Collections.emptyList(), - null, - fm.getJavaFileObjects(testFile)); - final Trees trees = Trees.instance(task); - final CompilationUnitTree cut = task.parse().iterator().next(); - final List typeAnnotationSpans = new ArrayList<>(); + //gather spans of the @TA annotations into typeAnnotationSpans: + JavacTask task = JavacTool.create().getTask(null, + fm, + null, + Collections.emptyList(), + null, + fm.getJavaFileObjects(testFile)); + final Trees trees = Trees.instance(task); + final CompilationUnitTree cut = task.parse().iterator().next(); + final List typeAnnotationSpans = new ArrayList<>(); - new TreePathScanner() { - @Override - public Void visitAnnotation(AnnotationTree node, Void p) { - if (node.getAnnotationType().getKind() == Kind.IDENTIFIER && - ((IdentifierTree) node.getAnnotationType()).getName().contentEquals("TA")) { - int start = (int) trees.getSourcePositions().getStartPosition(cut, node); - int end = (int) trees.getSourcePositions().getEndPosition(cut, node); - typeAnnotationSpans.add(new int[] {start, end}); - } - return null; - } - }.scan(cut, null); - - //sort the spans in the reverse order, to simplify removing them from the source: - Collections.sort(typeAnnotationSpans, new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - return o2[0] - o1[0]; - } - }); - - //verify the errors are produce correctly: - String originalSource = cut.getSourceFile().getCharContent(false).toString(); - - for (int[] toKeep : typeAnnotationSpans) { - //prepare updated source code by removing all the annotations except the toKeep one: - String updated = originalSource; - - for (int[] span : typeAnnotationSpans) { - if (span == toKeep) continue; - - updated = updated.substring(0, span[0]) + updated.substring(span[1]); - } - - //parse and verify: - JavaFileObject updatedFile = new TestFO(cut.getSourceFile().toUri(), updated); - DiagnosticCollector errors = new DiagnosticCollector<>(); - JavacTask task2 = JavacTool.create().getTask(null, - fm, - errors, - Arrays.asList("-source", "7"), - null, - Arrays.asList(updatedFile)); - task2.parse(); - - boolean found = false; - - for (Diagnostic d : errors.getDiagnostics()) { - if (d.getKind() == Diagnostic.Kind.ERROR && EXPECTED_ERRORS.contains(d.getCode())) { - if (found) { - throw new IllegalStateException("More than one expected error found."); + new TreePathScanner() { + @Override + public Void visitAnnotation(AnnotationTree node, Void p) { + if (node.getAnnotationType().getKind() == Kind.IDENTIFIER && + ((IdentifierTree) node.getAnnotationType()).getName().contentEquals("TA")) { + int start = (int) trees.getSourcePositions().getStartPosition(cut, node); + int end = (int) trees.getSourcePositions().getEndPosition(cut, node); + typeAnnotationSpans.add(new int[] {start, end}); } - found = true; + return null; } - } + }.scan(cut, null); - if (!found) - throw new IllegalStateException("Did not produce proper errors for: " + updated); + //sort the spans in the reverse order, to simplify removing them from the source: + Collections.sort(typeAnnotationSpans, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return o2[0] - o1[0]; + } + }); + + //verify the errors are produce correctly: + String originalSource = cut.getSourceFile().getCharContent(false).toString(); + + for (int[] toKeep : typeAnnotationSpans) { + //prepare updated source code by removing all the annotations except the toKeep one: + String updated = originalSource; + + for (int[] span : typeAnnotationSpans) { + if (span == toKeep) continue; + + updated = updated.substring(0, span[0]) + updated.substring(span[1]); + } + + //parse and verify: + JavaFileObject updatedFile = new TestFO(cut.getSourceFile().toUri(), updated); + DiagnosticCollector errors = new DiagnosticCollector<>(); + JavacTask task2 = JavacTool.create().getTask(null, + fm, + errors, + Arrays.asList("-source", "7"), + null, + Arrays.asList(updatedFile)); + task2.parse(); + + boolean found = false; + + for (Diagnostic d : errors.getDiagnostics()) { + if (d.getKind() == Diagnostic.Kind.ERROR && EXPECTED_ERRORS.contains(d.getCode())) { + if (found) { + throw new IllegalStateException("More than one expected error found."); + } + found = true; + } + } + + if (!found) + throw new IllegalStateException("Did not produce proper errors for: " + updated); + } } } diff --git a/langtools/test/tools/javac/api/6420409/T6420409.java b/langtools/test/tools/javac/api/6420409/T6420409.java index 48e733642f0..f5aca121b89 100644 --- a/langtools/test/tools/javac/api/6420409/T6420409.java +++ b/langtools/test/tools/javac/api/6420409/T6420409.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -46,21 +46,22 @@ public class T6420409 { public static void main(String... args) throws IOException { final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); - final StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - fm.setLocation(SOURCE_PATH, Arrays.asList(test_classes)); // switcheroo !!! - fm.setLocation(CLASS_PATH, Arrays.asList(test_src)); - fm.setLocation(CLASS_OUTPUT, Arrays.asList(test_classes)); - final Iterable compilationUnits = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(test_src, "T6420409.java"))); - tool.getTask(null, - fm, - null, - Arrays.asList("-proc:none"), - null, - compilationUnits).call(); - test(fm.getLocation(CLASS_PATH), test_src, CLASS_PATH); - test(fm.getLocation(SOURCE_PATH), test_classes, SOURCE_PATH); - test(fm.getLocation(CLASS_OUTPUT), test_classes, CLASS_OUTPUT); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + fm.setLocation(SOURCE_PATH, Arrays.asList(test_classes)); // switcheroo !!! + fm.setLocation(CLASS_PATH, Arrays.asList(test_src)); + fm.setLocation(CLASS_OUTPUT, Arrays.asList(test_classes)); + final Iterable compilationUnits = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(test_src, "T6420409.java"))); + tool.getTask(null, + fm, + null, + Arrays.asList("-proc:none"), + null, + compilationUnits).call(); + test(fm.getLocation(CLASS_PATH), test_src, CLASS_PATH); + test(fm.getLocation(SOURCE_PATH), test_classes, SOURCE_PATH); + test(fm.getLocation(CLASS_OUTPUT), test_classes, CLASS_OUTPUT); + } } static void test(Iterable path, File file, Location location) { diff --git a/langtools/test/tools/javac/api/6420464/T6420464.java b/langtools/test/tools/javac/api/6420464/T6420464.java index 80b6cd20a89..05af6f153c5 100644 --- a/langtools/test/tools/javac/api/6420464/T6420464.java +++ b/langtools/test/tools/javac/api/6420464/T6420464.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -38,15 +38,16 @@ public class T6420464 { public static void main(String... args) throws IOException { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager mgr = compiler.getStandardFileManager(null, null, null); - mgr.setLocation(StandardLocation.SOURCE_PATH, Collections.singleton(test_src)); - JavaFileObject f = mgr.getJavaFileForInput(StandardLocation.SOURCE_PATH, - "T6420464", - JavaFileObject.Kind.SOURCE); - if (!f.isNameCompatible("T6420464", JavaFileObject.Kind.SOURCE)) - throw new AssertionError("isNameCompatible(SOURCE) fails on " + f.toUri()); - if (f.isNameCompatible("T6420464", JavaFileObject.Kind.OTHER)) - throw new AssertionError("isNameCompatible(OTHER) fails on " + f.toUri()); - System.out.println("OK"); + try (StandardJavaFileManager mgr = compiler.getStandardFileManager(null, null, null)) { + mgr.setLocation(StandardLocation.SOURCE_PATH, Collections.singleton(test_src)); + JavaFileObject f = mgr.getJavaFileForInput(StandardLocation.SOURCE_PATH, + "T6420464", + JavaFileObject.Kind.SOURCE); + if (!f.isNameCompatible("T6420464", JavaFileObject.Kind.SOURCE)) + throw new AssertionError("isNameCompatible(SOURCE) fails on " + f.toUri()); + if (f.isNameCompatible("T6420464", JavaFileObject.Kind.OTHER)) + throw new AssertionError("isNameCompatible(OTHER) fails on " + f.toUri()); + System.out.println("OK"); + } } } diff --git a/langtools/test/tools/javac/api/6431435/T6431435.java b/langtools/test/tools/javac/api/6431435/T6431435.java index 307cc8ec5e5..da5f333ad13 100644 --- a/langtools/test/tools/javac/api/6431435/T6431435.java +++ b/langtools/test/tools/javac/api/6431435/T6431435.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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,18 +39,19 @@ public class T6431435 { String testSrc = System.getProperty("test.src", "."); String testClasses = System.getProperty("test.classes", "."); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); - fm.setLocation(StandardLocation.SOURCE_PATH, Arrays.asList(new File(testSrc))); - Iterable files = fm.getJavaFileObjectsFromFiles(Arrays.asList( - new File(testSrc, "A.java"))); - JavacTask task = tool.getTask(null, fm, null, null, null, files); - boolean ok = true; - ok &= check("parse", task.parse(), 1); // A.java - ok &= check("analyze", task.analyze(), 3); // A, Foo, p.B - ok &= check("generate", task.generate(), 5); // A, Foo, Foo$Baz, Foo$1, p.B - if (!ok) - throw new AssertionError("Test failed"); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); + fm.setLocation(StandardLocation.SOURCE_PATH, Arrays.asList(new File(testSrc))); + Iterable files = fm.getJavaFileObjectsFromFiles(Arrays.asList( + new File(testSrc, "A.java"))); + JavacTask task = tool.getTask(null, fm, null, null, null, files); + boolean ok = true; + ok &= check("parse", task.parse(), 1); // A.java + ok &= check("analyze", task.analyze(), 3); // A, Foo, p.B + ok &= check("generate", task.generate(), 5); // A, Foo, Foo$Baz, Foo$1, p.B + if (!ok) + throw new AssertionError("Test failed"); + } } private static boolean check(String name, Iterable iter, int expect) { diff --git a/langtools/test/tools/javac/api/7086261/T7086261.java b/langtools/test/tools/javac/api/7086261/T7086261.java index 47fae1b87f7..243622d6426 100644 --- a/langtools/test/tools/javac/api/7086261/T7086261.java +++ b/langtools/test/tools/javac/api/7086261/T7086261.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -66,10 +66,11 @@ public class T7086261 { void test() throws Throwable { JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); - JavaFileManager jfm = javac.getStandardFileManager(null, null, null); - JavaCompiler.CompilationTask task = - javac.getTask(null, jfm, new DiagnosticChecker(), null, null, Arrays.asList(new ErroneousSource())); - task.call(); + try (JavaFileManager jfm = javac.getStandardFileManager(null, null, null)) { + JavaCompiler.CompilationTask task = + javac.getTask(null, jfm, new DiagnosticChecker(), null, null, Arrays.asList(new ErroneousSource())); + task.call(); + } } public static void main(String[] args) throws Throwable { diff --git a/langtools/test/tools/javac/api/8007344/Test.java b/langtools/test/tools/javac/api/8007344/Test.java index 23f63b720c9..3ac8c7d7f4c 100644 --- a/langtools/test/tools/javac/api/8007344/Test.java +++ b/langtools/test/tools/javac/api/8007344/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -83,14 +83,15 @@ public class Test { File testSrc = new File(System.getProperty("test.src")); File thisFile = new File(testSrc, getClass().getName() + ".java"); JavacTool javac = JavacTool.create(); - StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null); - fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); - Iterable fos = fm.getJavaFileObjects(thisFile); - testAnnoProcessor(javac, fm, fos, out, EXPECT_DOC_COMMENTS); - testTaskListener(javac, fm, fos, out, EXPECT_DOC_COMMENTS); + try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) { + fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); + Iterable fos = fm.getJavaFileObjects(thisFile); + testAnnoProcessor(javac, fm, fos, out, EXPECT_DOC_COMMENTS); + testTaskListener(javac, fm, fos, out, EXPECT_DOC_COMMENTS); - if (errors > 0) - throw new Exception(errors + " errors occurred"); + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } } void testAnnoProcessor(JavacTool javac, StandardJavaFileManager fm, diff --git a/langtools/test/tools/javac/api/Sibling.java b/langtools/test/tools/javac/api/Sibling.java index 3b6acbb73f8..e02ac32fd15 100644 --- a/langtools/test/tools/javac/api/Sibling.java +++ b/langtools/test/tools/javac/api/Sibling.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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,17 +39,18 @@ import static javax.tools.JavaFileObject.Kind.CLASS; public class Sibling { public static void main(String... args) throws IOException { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); - JavaFileObject sibling = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File("Test.java"))) - .iterator().next(); - JavaFileObject classFile = fm.getJavaFileForOutput(CLASS_OUTPUT, - "foo.bar.baz.Test", - CLASS, - sibling); - File file = new File("Test.class").getAbsoluteFile(); - if (!classFile.toUri().equals(file.toURI())) - throw new AssertionError("Expected " + file.toURI() + ", got " + - classFile.toUri()); + try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { + JavaFileObject sibling = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File("Test.java"))) + .iterator().next(); + JavaFileObject classFile = fm.getJavaFileForOutput(CLASS_OUTPUT, + "foo.bar.baz.Test", + CLASS, + sibling); + File file = new File("Test.class").getAbsoluteFile(); + if (!classFile.toUri().equals(file.toURI())) + throw new AssertionError("Expected " + file.toURI() + ", got " + + classFile.toUri()); + } } } diff --git a/langtools/test/tools/javac/api/T6258271.java b/langtools/test/tools/javac/api/T6258271.java index 94f9db68d41..3fe73be52c6 100644 --- a/langtools/test/tools/javac/api/T6258271.java +++ b/langtools/test/tools/javac/api/T6258271.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ import java.util.Arrays; import javax.tools.*; public class T6258271 { - public static void main(String... args) { + public static void main(String... args) throws IOException { JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); DiagnosticListener dl = new DiagnosticListener() { public void report(Diagnostic message) { @@ -43,9 +43,10 @@ public class T6258271 { System.out.println(message); } }; - StandardJavaFileManager fm = javac.getStandardFileManager(dl, null, null); - Iterable files = - fm.getJavaFileObjectsFromStrings(Arrays.asList("nofile.java")); - javac.getTask(null, fm, dl, null, null, files).call(); + try (StandardJavaFileManager fm = javac.getStandardFileManager(dl, null, null)) { + Iterable files = + fm.getJavaFileObjectsFromStrings(Arrays.asList("nofile.java")); + javac.getTask(null, fm, dl, null, null, files).call(); + } } } diff --git a/langtools/test/tools/javac/api/T6265137.java b/langtools/test/tools/javac/api/T6265137.java index 1b86c565359..c37cf11a5db 100644 --- a/langtools/test/tools/javac/api/T6265137.java +++ b/langtools/test/tools/javac/api/T6265137.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ -29,11 +29,12 @@ */ import java.io.File; +import java.io.IOException; import java.util.Arrays; import javax.tools.*; public class T6265137 { - public static void main(String... args) { + public static void main(String... args) throws IOException { JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); DiagnosticListener dl = new DiagnosticListener() { public void report(Diagnostic message) { @@ -45,10 +46,11 @@ public class T6265137 { System.out.flush(); } }; - StandardJavaFileManager fm = javac.getStandardFileManager(dl, null, null); - String srcdir = System.getProperty("test.src"); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(srcdir, "T6265137a.java"))); - javac.getTask(null, fm, dl, Arrays.asList("-target","9"), null, files).call(); + try (StandardJavaFileManager fm = javac.getStandardFileManager(dl, null, null)) { + String srcdir = System.getProperty("test.src"); + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(srcdir, "T6265137a.java"))); + javac.getTask(null, fm, dl, Arrays.asList("-target","9"), null, files).call(); + } } } diff --git a/langtools/test/tools/javac/api/T6306137.java b/langtools/test/tools/javac/api/T6306137.java index 2d5865e6618..5165d9dbf4a 100644 --- a/langtools/test/tools/javac/api/T6306137.java +++ b/langtools/test/tools/javac/api/T6306137.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ -87,10 +87,18 @@ public class T6306137 { } } + void close() throws IOException { + fm.close(); + } + public static void main(String[] args) throws IOException { T6306137 self = new T6306137(); - self.test("utf-8", true); - self.test("ascii", false); - self.test("utf-8", true); + try { + self.test("utf-8", true); + self.test("ascii", false); + self.test("utf-8", true); + } finally { + self.close(); + } } } diff --git a/langtools/test/tools/javac/api/T6345974.java b/langtools/test/tools/javac/api/T6345974.java index f42a3b4c006..0fdbc1fa3c1 100644 --- a/langtools/test/tools/javac/api/T6345974.java +++ b/langtools/test/tools/javac/api/T6345974.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -45,17 +45,18 @@ public class T6345974 { public static void main(String[] args) throws Exception { PrintWriter out = new PrintWriter(System.out, true); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File testSrc = new File(System.getProperty("test.src")); - Iterable f = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "T6345974.java"))); - JavacTask task = tool.getTask(out, fm, null, null, null, f); - Iterable trees = task.parse(); - out.flush(); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File testSrc = new File(System.getProperty("test.src")); + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "T6345974.java"))); + JavacTask task = tool.getTask(out, fm, null, null, null, f); + Iterable trees = task.parse(); + out.flush(); - Scanner s = new Scanner(); - for (CompilationUnitTree t: trees) - s.scan(t, null); + Scanner s = new Scanner(); + for (CompilationUnitTree t: trees) + s.scan(t, null); + } } private static class Scanner extends TreeScanner { diff --git a/langtools/test/tools/javac/api/T6357331.java b/langtools/test/tools/javac/api/T6357331.java index 7ddd7b841e6..a1b4e2eac8f 100644 --- a/langtools/test/tools/javac/api/T6357331.java +++ b/langtools/test/tools/javac/api/T6357331.java @@ -33,42 +33,43 @@ import com.sun.source.util.*; public class T6357331 { - public static void main(String... args) { + public static void main(String... args) throws IOException { JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); PrintWriter out = new PrintWriter(new StringWriter()); List opts = Arrays.asList("-d", "."); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File thisFile = new File(System.getProperty("test.src"), "T6357331.java"); - Iterable files = fm.getJavaFileObjects(thisFile); - final JavacTask task = (JavacTask) (tool.getTask(out, fm, null, opts, null, files)); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File thisFile = new File(System.getProperty("test.src"), "T6357331.java"); + Iterable files = fm.getJavaFileObjects(thisFile); + final JavacTask task = (JavacTask) (tool.getTask(out, fm, null, opts, null, files)); - // set a listener to verify that IllegalStateException is not thrown - // during the compilation - task.setTaskListener(new TaskListener() { - public void started(TaskEvent e) { - task.getElements(); - task.getTypes(); - } - public void finished(TaskEvent e) { } - }); + // set a listener to verify that IllegalStateException is not thrown + // during the compilation + task.setTaskListener(new TaskListener() { + public void started(TaskEvent e) { + task.getElements(); + task.getTypes(); + } + public void finished(TaskEvent e) { } + }); - task.call(); + task.call(); - // now the compilation is over, we expect IllegalStateException (not NPE) - try { - task.getElements(); - throw new AssertionError("IllegalStateException not thrown"); - } - catch (IllegalStateException e) { - // expected - } + // now the compilation is over, we expect IllegalStateException (not NPE) + try { + task.getElements(); + throw new AssertionError("IllegalStateException not thrown"); + } + catch (IllegalStateException e) { + // expected + } - try { - task.getTypes(); - throw new AssertionError("IllegalStateException not thrown"); - } - catch (IllegalStateException e) { - // expected + try { + task.getTypes(); + throw new AssertionError("IllegalStateException not thrown"); + } + catch (IllegalStateException e) { + // expected + } } } } diff --git a/langtools/test/tools/javac/api/T6358786.java b/langtools/test/tools/javac/api/T6358786.java index 1faf5a74b22..63d2462f471 100644 --- a/langtools/test/tools/javac/api/T6358786.java +++ b/langtools/test/tools/javac/api/T6358786.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ -44,16 +44,17 @@ import javax.tools.*; public class T6358786 { public static void main(String... args) throws IOException { JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - String srcdir = System.getProperty("test.src"); - File file = new File(srcdir, args[0]); - JavacTaskImpl task = (JavacTaskImpl)tool.getTask(null, fm, null, null, null, fm.getJavaFileObjectsFromFiles(Arrays.asList(file))); - Elements elements = task.getElements(); - for (TypeElement clazz : task.enter(task.parse())) { - String doc = elements.getDocComment(clazz); - if (doc == null) - throw new AssertionError(clazz.getSimpleName() + ": no doc comment"); - System.out.format("%s: %s%n", clazz.getSimpleName(), doc); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + String srcdir = System.getProperty("test.src"); + File file = new File(srcdir, args[0]); + JavacTaskImpl task = (JavacTaskImpl)tool.getTask(null, fm, null, null, null, fm.getJavaFileObjectsFromFiles(Arrays.asList(file))); + Elements elements = task.getElements(); + for (TypeElement clazz : task.enter(task.parse())) { + String doc = elements.getDocComment(clazz); + if (doc == null) + throw new AssertionError(clazz.getSimpleName() + ": no doc comment"); + System.out.format("%s: %s%n", clazz.getSimpleName(), doc); + } } } } diff --git a/langtools/test/tools/javac/api/T6358955.java b/langtools/test/tools/javac/api/T6358955.java index 001469e8957..805c501a459 100644 --- a/langtools/test/tools/javac/api/T6358955.java +++ b/langtools/test/tools/javac/api/T6358955.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -36,34 +36,35 @@ import static javax.tools.JavaFileObject.Kind.*; public class T6358955 { public static void main(String[] args) throws Exception { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null); + try (StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null)) { - File dir = new File("temp" + args.hashCode()); - if (!dir.exists()) - dir.mkdir(); - if (!dir.isDirectory()) - throw new AssertionError("Not a directory " + dir); + File dir = new File("temp" + args.hashCode()); + if (!dir.exists()) + dir.mkdir(); + if (!dir.isDirectory()) + throw new AssertionError("Not a directory " + dir); - try { - jfm.setLocation(StandardLocation.CLASS_OUTPUT, - Arrays.asList(dir.getCanonicalFile().getParentFile())); try { - jfm.getFileForInput(StandardLocation.CLASS_OUTPUT, "", dir.getPath()); - throw new AssertionError("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - System.out.println("OK: " + e.getLocalizedMessage()); - } - try { - jfm.getJavaFileObjectsFromFiles(Arrays.asList(dir)); - throw new AssertionError("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - System.out.println("OK: " + e.getLocalizedMessage()); - } - } finally { - try { - dir.delete(); // cleanup - } catch (Throwable t) { - t.printStackTrace(); + jfm.setLocation(StandardLocation.CLASS_OUTPUT, + Arrays.asList(dir.getCanonicalFile().getParentFile())); + try { + jfm.getFileForInput(StandardLocation.CLASS_OUTPUT, "", dir.getPath()); + throw new AssertionError("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + System.out.println("OK: " + e.getLocalizedMessage()); + } + try { + jfm.getJavaFileObjectsFromFiles(Arrays.asList(dir)); + throw new AssertionError("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + System.out.println("OK: " + e.getLocalizedMessage()); + } + } finally { + try { + dir.delete(); // cleanup + } catch (Throwable t) { + t.printStackTrace(); + } } } } diff --git a/langtools/test/tools/javac/api/T6392782.java b/langtools/test/tools/javac/api/T6392782.java index 9bb010070d1..79379686143 100644 --- a/langtools/test/tools/javac/api/T6392782.java +++ b/langtools/test/tools/javac/api/T6392782.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -38,21 +38,22 @@ public class T6392782 { public static void main(String... args) throws IOException { String testSrc = System.getProperty("test.src", "."); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6392782.class.getName()+".java"))); - JavacTask task = tool.getTask(null, fm, null, null, null, files); - Iterable trees = task.parse(); - TreeScanner scanner = new MyScanner(); - check(scanner, 6, scanner.scan(trees, null)); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6392782.class.getName()+".java"))); + JavacTask task = tool.getTask(null, fm, null, null, null, files); + Iterable trees = task.parse(); + TreeScanner scanner = new MyScanner(); + check(scanner, 6, scanner.scan(trees, null)); - CountNodes nodeCounter = new CountNodes(); - // 359 nodes with the regular parser; 360 nodes with EndPosParser - // We automatically switch to EndPosParser when calling JavacTask.parse() - check(nodeCounter, 360, nodeCounter.scan(trees, null)); + CountNodes nodeCounter = new CountNodes(); + // 359 nodes with the regular parser; 360 nodes with EndPosParser + // We automatically switch to EndPosParser when calling JavacTask.parse() + check(nodeCounter, 362, nodeCounter.scan(trees, null)); - CountIdentifiers idCounter = new CountIdentifiers(); - check(idCounter, 107, idCounter.scan(trees, null)); + CountIdentifiers idCounter = new CountIdentifiers(); + check(idCounter, 107, idCounter.scan(trees, null)); + } } private static void check(TreeScanner scanner, int expect, int found) { diff --git a/langtools/test/tools/javac/api/T6397104.java b/langtools/test/tools/javac/api/T6397104.java index a3d919c057d..a0d9f114b3e 100644 --- a/langtools/test/tools/javac/api/T6397104.java +++ b/langtools/test/tools/javac/api/T6397104.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -65,16 +65,15 @@ public class T6397104 { void test(boolean hasLocation, File siblingFile, String relName, String expectedPath) throws Exception { - StandardJavaFileManager fm; - if (hasLocation) { - for (Location location : StandardLocation.values()) { - fm = tool.getStandardFileManager(null, null, null); - fm.setLocation(location, Arrays.asList(new File("."))); - test(fm, location, siblingFile, relName, expectedPath); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + if (hasLocation) { + for (Location location : StandardLocation.values()) { + fm.setLocation(location, Arrays.asList(new File("."))); + test(fm, location, siblingFile, relName, expectedPath); + } + } else { + test(fm, CLASS_OUTPUT, siblingFile, relName, expectedPath); } - } else { - fm = tool.getStandardFileManager(null, null, null); - test(fm, CLASS_OUTPUT, siblingFile, relName, expectedPath); } } diff --git a/langtools/test/tools/javac/api/T6400205.java b/langtools/test/tools/javac/api/T6400205.java index c0e50dbeac2..f67ab29361a 100644 --- a/langtools/test/tools/javac/api/T6400205.java +++ b/langtools/test/tools/javac/api/T6400205.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -28,22 +28,24 @@ * @author Peter von der Ah\u00e9 */ +import java.io.IOException; import javax.tools.*; import static javax.tools.StandardLocation.*; public class T6400205 { - public static void main(String... args) { - JavaFileManager fm = - ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null); - try { - fm.getClassLoader(null); - throw new AssertionError("NullPointerException not thrown"); - } catch (NullPointerException e) { - // expected result + public static void main(String... args) throws IOException { + try (JavaFileManager fm = + ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null)) { + try { + fm.getClassLoader(null); + throw new AssertionError("NullPointerException not thrown"); + } catch (NullPointerException e) { + // expected result + } + ClassLoader cl = fm.getClassLoader(locationFor("bogus")); + if (cl != null) + throw new AssertionError("non-null class loader for bogus location"); + System.err.println("Test PASSED."); } - ClassLoader cl = fm.getClassLoader(locationFor("bogus")); - if (cl != null) - throw new AssertionError("non-null class loader for bogus location"); - System.err.println("Test PASSED."); } } diff --git a/langtools/test/tools/javac/api/T6400207.java b/langtools/test/tools/javac/api/T6400207.java index 01a740f2443..2977d5b785d 100644 --- a/langtools/test/tools/javac/api/T6400207.java +++ b/langtools/test/tools/javac/api/T6400207.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -61,28 +61,29 @@ public class T6400207 { } public static void main(String... args) throws Exception { - JavaFileManager fm = - ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null); - JavaFileManager.Location bogusLocation = locationFor("bogus"); - JavaFileManager.Location knownLocation = CLASS_PATH; - String packageName = "java.lang"; - Set kinds = EnumSet.of(CLASS); + try (JavaFileManager fm = + ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null)) { + JavaFileManager.Location bogusLocation = locationFor("bogus"); + JavaFileManager.Location knownLocation = CLASS_PATH; + String packageName = "java.lang"; + Set kinds = EnumSet.of(CLASS); - for (StandardLocation location : StandardLocation.values()) { - if (location != locationFor(location.getName())) - throw new AssertionError(location + " != locationFor(" + - location.getName() + ")"); + for (StandardLocation location : StandardLocation.values()) { + if (location != locationFor(location.getName())) + throw new AssertionError(location + " != locationFor(" + + location.getName() + ")"); + } + + testList(fm, null, null, null); + testList(fm, bogusLocation, packageName, kinds); + testList(fm, knownLocation, packageName, kinds); + testList(fm, null, packageName, kinds); + testList(fm, knownLocation, null, kinds); + testList(fm, knownLocation, packageName, null); + testList(fm, bogusLocation, null, kinds); + testList(fm, bogusLocation, packageName, null); + + System.err.println("Test PASSED."); } - - testList(fm, null, null, null); - testList(fm, bogusLocation, packageName, kinds); - testList(fm, knownLocation, packageName, kinds); - testList(fm, null, packageName, kinds); - testList(fm, knownLocation, null, kinds); - testList(fm, knownLocation, packageName, null); - testList(fm, bogusLocation, null, kinds); - testList(fm, bogusLocation, packageName, null); - - System.err.println("Test PASSED."); } } diff --git a/langtools/test/tools/javac/api/T6412669.java b/langtools/test/tools/javac/api/T6412669.java index de7e76051a3..c8fc966b46e 100644 --- a/langtools/test/tools/javac/api/T6412669.java +++ b/langtools/test/tools/javac/api/T6412669.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -64,22 +64,23 @@ public class T6412669 extends AbstractProcessor { //System.err.println("toolsClasses: " + toolsClasses); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(testClasses, toolsClasses)); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6412669.class.getName()+".java"))); - String[] opts = { "-proc:only", "-processor", T6412669.class.getName()}; - StringWriter sw = new StringWriter(); - JavacTask task = tool.getTask(sw, fm, null, Arrays.asList(opts), null, files); - boolean ok = task.call(); - String out = sw.toString(); - if (!out.isEmpty()) - System.err.println(out); - if (!ok) - throw new AssertionError("compilation of test program failed"); - // verify we found an annotated element to exercise the SourcePositions API - if (!out.contains("processing element")) - throw new AssertionError("expected text not found in compilation output"); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(testClasses, toolsClasses)); + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6412669.class.getName()+".java"))); + String[] opts = { "-proc:only", "-processor", T6412669.class.getName()}; + StringWriter sw = new StringWriter(); + JavacTask task = tool.getTask(sw, fm, null, Arrays.asList(opts), null, files); + boolean ok = task.call(); + String out = sw.toString(); + if (!out.isEmpty()) + System.err.println(out); + if (!ok) + throw new AssertionError("compilation of test program failed"); + // verify we found an annotated element to exercise the SourcePositions API + if (!out.contains("processing element")) + throw new AssertionError("expected text not found in compilation output"); + } } public boolean process(Set annotations, RoundEnvironment roundEnv) { diff --git a/langtools/test/tools/javac/api/T6419926.java b/langtools/test/tools/javac/api/T6419926.java index 320dac0699f..bcb2e3d741f 100644 --- a/langtools/test/tools/javac/api/T6419926.java +++ b/langtools/test/tools/javac/api/T6419926.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -35,17 +35,18 @@ import javax.tools.*; public class T6419926 { public static void main(String[] argv) throws Exception { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager mgr = compiler.getStandardFileManager( new DiagnosticCollector(), null, null); - System.out.println( new File( new File(".").toURI() ).getAbsolutePath() ); - mgr.setLocation(StandardLocation.CLASS_OUTPUT, - Collections.singleton(new File("."))); + try (StandardJavaFileManager mgr = compiler.getStandardFileManager( new DiagnosticCollector(), null, null)) { + System.out.println( new File( new File(".").toURI() ).getAbsolutePath() ); + mgr.setLocation(StandardLocation.CLASS_OUTPUT, + Collections.singleton(new File("."))); - FileObject fo = mgr.getFileForOutput(StandardLocation.CLASS_OUTPUT, - "", "file.to.delete", null); - URI uri = fo.toUri(); - System.out.println( uri ); + FileObject fo = mgr.getFileForOutput(StandardLocation.CLASS_OUTPUT, + "", "file.to.delete", null); + URI uri = fo.toUri(); + System.out.println( uri ); - if (!"file".equals(uri.getScheme())) - throw new Exception("unexpected scheme for uri: " + uri.getScheme()); + if (!"file".equals(uri.getScheme())) + throw new Exception("unexpected scheme for uri: " + uri.getScheme()); + } } } diff --git a/langtools/test/tools/javac/api/T6430241.java b/langtools/test/tools/javac/api/T6430241.java index 8916d3d36c1..bdcc068aa25 100644 --- a/langtools/test/tools/javac/api/T6430241.java +++ b/langtools/test/tools/javac/api/T6430241.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -134,21 +134,22 @@ System.err.println("test task API: " + pcp); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { - if (pcp != null) - fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, pcp); + if (pcp != null) + fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, pcp); - Iterable files = fm.getJavaFileObjects(testFile); + Iterable files = fm.getJavaFileObjects(testFile); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - JavacTask task = tool.getTask(pw, fm, null, null, null, files); - boolean ok = task.call(); - String out = showOutput(sw.toString()); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + JavacTask task = tool.getTask(pw, fm, null, null, null, files); + boolean ok = task.call(); + String out = showOutput(sw.toString()); - checkCompilationOK(ok); - checkOutput(out, expectWarnings); + checkCompilationOK(ok); + checkOutput(out, expectWarnings); + } } //----- utility methods diff --git a/langtools/test/tools/javac/api/T6431879.java b/langtools/test/tools/javac/api/T6431879.java index 666448fd2d7..fff0a87cadc 100644 --- a/langtools/test/tools/javac/api/T6431879.java +++ b/langtools/test/tools/javac/api/T6431879.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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,18 +39,18 @@ public class T6431879 { String testSrc = System.getProperty("test.src", "."); String testClasses = System.getProperty("test.classes", "."); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6431879.class.getName()+".java"))); - JavacTask task = tool.getTask(null, fm, null, null, null, files); - Iterable trees = task.parse(); - TreeScanner dependencyScanner = new DependencyScanner(); - Trees treeUtil = Trees.instance(task); - for (CompilationUnitTree unit : trees) { - //System.err.println("scan " + unit); - dependencyScanner.scan(unit, treeUtil); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6431879.class.getName()+".java"))); + JavacTask task = tool.getTask(null, fm, null, null, null, files); + Iterable trees = task.parse(); + TreeScanner dependencyScanner = new DependencyScanner(); + Trees treeUtil = Trees.instance(task); + for (CompilationUnitTree unit : trees) { + //System.err.println("scan " + unit); + dependencyScanner.scan(unit, treeUtil); + } } - } private static class DependencyScanner extends TreePathScanner { diff --git a/langtools/test/tools/javac/api/T6483788.java b/langtools/test/tools/javac/api/T6483788.java index 9761f1cb75b..6b9c03cb3e4 100644 --- a/langtools/test/tools/javac/api/T6483788.java +++ b/langtools/test/tools/javac/api/T6483788.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, 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 @@ -42,14 +42,15 @@ public class T6483788 { void run() throws Exception { File jar = createJar(); JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); - fm.setLocation(StandardLocation.CLASS_PATH, Collections.singleton(jar)); - JavaFileObject fo = fm.getJavaFileForInput(StandardLocation.CLASS_PATH, "dummy", JavaFileObject.Kind.CLASS); - System.err.println("file: " + fo); - URI uri = fo.toUri(); - System.err.println("uri: " + uri); - if (uri.toString().contains(" ")) - throw new Exception("unexpected space character found"); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + fm.setLocation(StandardLocation.CLASS_PATH, Collections.singleton(jar)); + JavaFileObject fo = fm.getJavaFileForInput(StandardLocation.CLASS_PATH, "dummy", JavaFileObject.Kind.CLASS); + System.err.println("file: " + fo); + URI uri = fo.toUri(); + System.err.println("uri: " + uri); + if (uri.toString().contains(" ")) + throw new Exception("unexpected space character found"); + } } File createJar() throws IOException { diff --git a/langtools/test/tools/javac/api/T6501502.java b/langtools/test/tools/javac/api/T6501502.java index 6faf3409e72..396020d1f52 100644 --- a/langtools/test/tools/javac/api/T6501502.java +++ b/langtools/test/tools/javac/api/T6501502.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, 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 @@ -46,16 +46,18 @@ public class T6501502 { // we test a number of platform-independent paths. void run() throws Exception { JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - fm = c.getStandardFileManager(null, null, null); - System.err.println(System.getProperties()); - File tmpDir = new File(System.getProperty("java.io.tmpdir")); - File testSrcDir = new File(System.getProperty("test.src")); - File testClassesDir = new File(System.getProperty("test.classes")); - test(new File("abc.tmp")); - test(new File(tmpDir, "bad.file")); - test(new File(testSrcDir, "T6501501.java")); - test(new File(testClassesDir, "T6501501.class")); - test(new File("a b")); + try (StandardJavaFileManager sfm = c.getStandardFileManager(null, null, null)) { + fm = sfm; + System.err.println(System.getProperties()); + File tmpDir = new File(System.getProperty("java.io.tmpdir")); + File testSrcDir = new File(System.getProperty("test.src")); + File testClassesDir = new File(System.getProperty("test.classes")); + test(new File("abc.tmp")); + test(new File(tmpDir, "bad.file")); + test(new File(testSrcDir, "T6501501.java")); + test(new File(testClassesDir, "T6501501.class")); + test(new File("a b")); + } } void test(File f) throws Exception { diff --git a/langtools/test/tools/javac/api/TestClientCodeWrapper.java b/langtools/test/tools/javac/api/TestClientCodeWrapper.java index 29982fadf4e..16920c4478a 100644 --- a/langtools/test/tools/javac/api/TestClientCodeWrapper.java +++ b/langtools/test/tools/javac/api/TestClientCodeWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -56,34 +56,36 @@ public class TestClientCodeWrapper extends JavacTestingAbstractProcessor { */ void run() throws Exception { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - defaultFileManager = compiler.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { + defaultFileManager = fm; - for (Method m: getMethodsExcept(JavaFileManager.class, "close", "getJavaFileForInput")) { - test(m); + for (Method m: getMethodsExcept(JavaFileManager.class, "close", "getJavaFileForInput")) { + test(m); + } + + for (Method m: getMethodsExcept(FileObject.class, "delete")) { + test(m); + } + + for (Method m: getMethods(JavaFileObject.class)) { + test(m); + } + + for (Method m: getMethodsExcept(Processor.class, "getCompletions")) { + test(m); + } + + for (Method m: DiagnosticListener.class.getDeclaredMethods()) { + test(m); + } + + for (Method m: TaskListener.class.getDeclaredMethods()) { + test(m); + } + + if (errors > 0) + throw new Exception(errors + " errors occurred"); } - - for (Method m: getMethodsExcept(FileObject.class, "delete")) { - test(m); - } - - for (Method m: getMethods(JavaFileObject.class)) { - test(m); - } - - for (Method m: getMethodsExcept(Processor.class, "getCompletions")) { - test(m); - } - - for (Method m: DiagnosticListener.class.getDeclaredMethods()) { - test(m); - } - - for (Method m: TaskListener.class.getDeclaredMethods()) { - test(m); - } - - if (errors > 0) - throw new Exception(errors + " errors occurred"); } /** Get a sorted set of the methods declared on a class. */ diff --git a/langtools/test/tools/javac/api/TestDocComments.java b/langtools/test/tools/javac/api/TestDocComments.java index ab47db9329c..168af1a375b 100644 --- a/langtools/test/tools/javac/api/TestDocComments.java +++ b/langtools/test/tools/javac/api/TestDocComments.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -52,23 +52,23 @@ public class TestDocComments { File file = new File(testSrc, "TestDocComments.java"); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + Iterable fileObjects = fm.getJavaFileObjects(file); + JavacTask task = tool.getTask(pw, fm, null, null, null, fileObjects); + Iterable units = task.parse(); + Trees trees = Trees.instance(task); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - Iterable fileObjects = fm.getJavaFileObjects(file); - JavacTask task = tool.getTask(pw, fm, null, null, null, fileObjects); - Iterable units = task.parse(); - Trees trees = Trees.instance(task); + CommentScanner s = new CommentScanner(); + int n = s.scan(units, trees); - CommentScanner s = new CommentScanner(); - int n = s.scan(units, trees); + if (n != 12) + error("Unexpected number of doc comments found: " + n); - if (n != 12) - error("Unexpected number of doc comments found: " + n); - - if (errors > 0) - throw new Exception(errors + " errors occurred"); + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } } /** diff --git a/langtools/test/tools/javac/api/TestGetElementReference.java b/langtools/test/tools/javac/api/TestGetElementReference.java index aa62b924d85..39d0ec7fef1 100644 --- a/langtools/test/tools/javac/api/TestGetElementReference.java +++ b/langtools/test/tools/javac/api/TestGetElementReference.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -50,31 +50,32 @@ public class TestGetElementReference { public static void main(String... args) throws IOException { File source = new File(System.getProperty("test.src", "."), "TestGetElementReferenceData.java").getAbsoluteFile(); - StandardJavaFileManager fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null); - DiagnosticCollector diagnostics = new DiagnosticCollector<>(); - JavacTask ct = (JavacTask) ToolProvider.getSystemJavaCompiler().getTask(null, null, diagnostics, Arrays.asList("-Xjcov"), null, fm.getJavaFileObjects(source)); - Trees trees = Trees.instance(ct); - CompilationUnitTree cut = ct.parse().iterator().next(); + try (StandardJavaFileManager fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null)) { + DiagnosticCollector diagnostics = new DiagnosticCollector<>(); + JavacTask ct = (JavacTask) ToolProvider.getSystemJavaCompiler().getTask(null, null, diagnostics, Arrays.asList("-Xjcov"), null, fm.getJavaFileObjects(source)); + Trees trees = Trees.instance(ct); + CompilationUnitTree cut = ct.parse().iterator().next(); - ct.analyze(); + ct.analyze(); - for (Diagnostic d : diagnostics.getDiagnostics()) { - if (d.getKind() == Diagnostic.Kind.ERROR) { - throw new IllegalStateException("Should have been attributed without errors: " + diagnostics.getDiagnostics()); + for (Diagnostic d : diagnostics.getDiagnostics()) { + if (d.getKind() == Diagnostic.Kind.ERROR) { + throw new IllegalStateException("Should have been attributed without errors: " + diagnostics.getDiagnostics()); + } } - } - Pattern p = Pattern.compile("/\\*getElement:(.*?)\\*/"); - Matcher m = p.matcher(cut.getSourceFile().getCharContent(false)); + Pattern p = Pattern.compile("/\\*getElement:(.*?)\\*/"); + Matcher m = p.matcher(cut.getSourceFile().getCharContent(false)); - while (m.find()) { - TreePath tp = pathFor(trees, cut, m.start() - 1); - Element found = trees.getElement(tp); - String expected = m.group(1); - String actual = found != null ? found.getKind() + ":" + symbolToString(found) : ""; + while (m.find()) { + TreePath tp = pathFor(trees, cut, m.start() - 1); + Element found = trees.getElement(tp); + String expected = m.group(1); + String actual = found != null ? found.getKind() + ":" + symbolToString(found) : ""; - if (!expected.equals(actual)) { - throw new IllegalStateException("expected=" + expected + "; actual=" + actual); + if (!expected.equals(actual)) { + throw new IllegalStateException("expected=" + expected + "; actual=" + actual); + } } } } diff --git a/langtools/test/tools/javac/api/TestGetScope.java b/langtools/test/tools/javac/api/TestGetScope.java index 40cf8c9cd3f..9892ae5c19c 100644 --- a/langtools/test/tools/javac/api/TestGetScope.java +++ b/langtools/test/tools/javac/api/TestGetScope.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -29,6 +29,7 @@ import com.sun.source.tree.IdentifierTree; import java.io.File; +import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -51,24 +52,25 @@ import javax.lang.model.SourceVersion; @SupportedAnnotationTypes("*") public class TestGetScope extends AbstractProcessor { - public static void main(String... args) { + public static void main(String... args) throws IOException { new TestGetScope().run(); } - public void run() { + public void run() throws IOException { File srcDir = new File(System.getProperty("test.src")); File thisFile = new File(srcDir, getClass().getName() + ".java"); JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { - List opts = Arrays.asList("-proc:only", "-doe"); - Iterable files = fm.getJavaFileObjects(thisFile); - JavacTask t = (JavacTask) c.getTask(null, fm, null, opts, null, files); - t.setProcessors(Collections.singleton(this)); - boolean ok = t.call(); - if (!ok) - throw new Error("compilation failed"); + List opts = Arrays.asList("-proc:only", "-doe"); + Iterable files = fm.getJavaFileObjects(thisFile); + JavacTask t = (JavacTask) c.getTask(null, fm, null, opts, null, files); + t.setProcessors(Collections.singleton(this)); + boolean ok = t.call(); + if (!ok) + throw new Error("compilation failed"); + } } @Override diff --git a/langtools/test/tools/javac/api/TestJavacTask.java b/langtools/test/tools/javac/api/TestJavacTask.java index 3e013775466..24efb7e17f8 100644 --- a/langtools/test/tools/javac/api/TestJavacTask.java +++ b/langtools/test/tools/javac/api/TestJavacTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ -41,8 +41,8 @@ import javax.tools.ToolProvider; public class TestJavacTask { static final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + static final StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); static JavacTaskImpl getTask(File... file) { - StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); Iterable files = fm.getJavaFileObjectsFromFiles(Arrays.asList(file)); return (JavacTaskImpl)compiler.getTask(null, fm, null, null, null, files); @@ -69,7 +69,11 @@ public class TestJavacTask { } public static void main(String... args) throws IOException { - basicTest(args); - checkKindError(); + try { + basicTest(args); + checkKindError(); + } finally { + fm.close(); + } } } diff --git a/langtools/test/tools/javac/api/TestJavacTask_Lock.java b/langtools/test/tools/javac/api/TestJavacTask_Lock.java index e3fc609d4c8..1d71c4b5df7 100644 --- a/langtools/test/tools/javac/api/TestJavacTask_Lock.java +++ b/langtools/test/tools/javac/api/TestJavacTask_Lock.java @@ -67,15 +67,18 @@ public class TestJavacTask_Lock { void run() throws Exception { comp = ToolProvider.getSystemJavaCompiler(); fm = comp.getStandardFileManager(null, null, null); - - for (MethodKind first: MethodKind.values()) { - for (MethodKind second: MethodKind.values()) { - test(first, second); + try { + for (MethodKind first: MethodKind.values()) { + for (MethodKind second: MethodKind.values()) { + test(first, second); + } } - } - if (errors > 0) - throw new Exception(errors + " errors found"); + if (errors > 0) + throw new Exception(errors + " errors found"); + } finally { + fm.close(); + } } void test(MethodKind first, MethodKind second) { diff --git a/langtools/test/tools/javac/api/TestJavacTask_Multiple.java b/langtools/test/tools/javac/api/TestJavacTask_Multiple.java index dc78d82498d..8ab5482bef2 100644 --- a/langtools/test/tools/javac/api/TestJavacTask_Multiple.java +++ b/langtools/test/tools/javac/api/TestJavacTask_Multiple.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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,16 +68,19 @@ public class TestJavacTask_Multiple { void run() throws Exception { JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); - for (TestKind tk: TestKind.values()) { - test(comp, fm, tk); - } + try { + for (TestKind tk: TestKind.values()) { + test(comp, fm, tk); + } - int expect = TestKind.values().length * MAX_TASKS; - if (count != expect) { - throw new Exception("Unexpected number of tests completed: " + count - + ", expected: " + expect); + int expect = TestKind.values().length * MAX_TASKS; + if (count != expect) { + throw new Exception("Unexpected number of tests completed: " + count + + ", expected: " + expect); + } + } finally { + fm.close(); } - } void test(JavaCompiler comp, StandardJavaFileManager fm, TestKind tk) { diff --git a/langtools/test/tools/javac/api/TestJavacTask_ParseAttrGen.java b/langtools/test/tools/javac/api/TestJavacTask_ParseAttrGen.java index 44e1c82fd71..93e2eb084f5 100644 --- a/langtools/test/tools/javac/api/TestJavacTask_ParseAttrGen.java +++ b/langtools/test/tools/javac/api/TestJavacTask_ParseAttrGen.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -45,14 +45,17 @@ public class TestJavacTask_ParseAttrGen { void run() throws Exception { comp = ToolProvider.getSystemJavaCompiler(); fm = comp.getStandardFileManager(null, null, null); - - final boolean[] booleanValues = { false, true }; - for (boolean pk: booleanValues) { - for (boolean ak: booleanValues) { - for (boolean gk: booleanValues) { - test(pk, ak, gk); + try { + final boolean[] booleanValues = { false, true }; + for (boolean pk: booleanValues) { + for (boolean ak: booleanValues) { + for (boolean gk: booleanValues) { + test(pk, ak, gk); + } } } + } finally { + fm.close(); } } diff --git a/langtools/test/tools/javac/api/TestSearchPaths.java b/langtools/test/tools/javac/api/TestSearchPaths.java index 4e2a4ff7a8b..3aa39320fa8 100644 --- a/langtools/test/tools/javac/api/TestSearchPaths.java +++ b/langtools/test/tools/javac/api/TestSearchPaths.java @@ -76,30 +76,33 @@ public class TestSearchPaths { void run() throws Exception { compiler = ToolProvider.getSystemJavaCompiler(); fileManager = compiler.getStandardFileManager(null, null, null); + try { + // basic output path + testClassOutput(); - // basic output path - testClassOutput(); + // basic search paths + testClassPath(); + testSourcePath(); + testPlatformClassPath(); - // basic search paths - testClassPath(); - testSourcePath(); - testPlatformClassPath(); + // annotation processing + testAnnotationProcessorPath(); + testSourceOutput(); - // annotation processing - testAnnotationProcessorPath(); - testSourceOutput(); + // javah equivalent + testNativeHeaderOutput(); - // javah equivalent - testNativeHeaderOutput(); + // future-proof: guard against new StandardLocations being added + if (!tested.equals(EnumSet.allOf(StandardLocation.class))) { + error("not all standard locations have been tested"); + out.println("not yet tested: " + EnumSet.complementOf(tested)); + } - // future-proof: guard against new StandardLocations being added - if (!tested.equals(EnumSet.allOf(StandardLocation.class))) { - error("not all standard locations have been tested"); - out.println("not yet tested: " + EnumSet.complementOf(tested)); - } - - if (errors > 0) { - throw new Exception(errors + " errors occurred"); + if (errors > 0) { + throw new Exception(errors + " errors occurred"); + } + } finally { + fileManager.close(); } } diff --git a/langtools/test/tools/javac/api/TestTreePath.java b/langtools/test/tools/javac/api/TestTreePath.java index a1593949618..a642a318100 100644 --- a/langtools/test/tools/javac/api/TestTreePath.java +++ b/langtools/test/tools/javac/api/TestTreePath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -105,17 +105,18 @@ public class TestTreePath extends AbstractProcessor { public void run() throws IOException { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fileManager - = compiler.getStandardFileManager(null, null, null); - Iterable tests - = fileManager.getJavaFileObjects(writeTestFile()); + try (StandardJavaFileManager fileManager + = compiler.getStandardFileManager(null, null, null)) { + Iterable tests + = fileManager.getJavaFileObjects(writeTestFile()); - JavaCompiler.CompilationTask task = - ToolProvider.getSystemJavaCompiler().getTask( - null, null, null, - Arrays.asList("-processor", this.getClass().getName()), null, - tests); - task.call(); + JavaCompiler.CompilationTask task = + ToolProvider.getSystemJavaCompiler().getTask( + null, null, null, + Arrays.asList("-processor", this.getClass().getName()), null, + tests); + task.call(); + } } public static void main(String[] args) throws IOException { diff --git a/langtools/test/tools/javac/api/TestTrees.java b/langtools/test/tools/javac/api/TestTrees.java index a95e9a2e537..0db7bb8fb8f 100644 --- a/langtools/test/tools/javac/api/TestTrees.java +++ b/langtools/test/tools/javac/api/TestTrees.java @@ -74,29 +74,30 @@ public class TestTrees extends AbstractProcessor { } }; - StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrcDir, self + ".java"))); + try (StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null)) { + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrcDir, self + ".java"))); - Iterable opts = Arrays.asList("-d", ".", "-XDcompilePolicy=simple"); + Iterable opts = Arrays.asList("-d", ".", "-XDcompilePolicy=simple"); - System.err.println("simple compilation, no processing"); - JavacTask task = tool.getTask(out, fm, dl, opts, null, files); - task.setTaskListener(new MyTaskListener(task)); - if (!task.call()) - throw new AssertionError("compilation failed"); + System.err.println("simple compilation, no processing"); + JavacTask task = tool.getTask(out, fm, dl, opts, null, files); + task.setTaskListener(new MyTaskListener(task)); + if (!task.call()) + throw new AssertionError("compilation failed"); - opts = Arrays.asList("-d", ".", "-processorpath", testClassDir, "-processor", self, - "-XDcompilePolicy=simple"); + opts = Arrays.asList("-d", ".", "-processorpath", testClassDir, "-processor", self, + "-XDcompilePolicy=simple"); - System.err.println(); - System.err.println("compilation with processing"); - task = tool.getTask(out, fm, dl,opts, null, files); - if (!task.call()) - throw new AssertionError("compilation failed"); + System.err.println(); + System.err.println("compilation with processing"); + task = tool.getTask(out, fm, dl,opts, null, files); + if (!task.call()) + throw new AssertionError("compilation failed"); - if (errors > 0) - throw new AssertionError(errors + " errors occurred"); + if (errors > 0) + throw new AssertionError(errors + " errors occurred"); + } } void testElement(Trees trees, Element e) { diff --git a/langtools/test/tools/javac/api/taskListeners/CompileEvent.java b/langtools/test/tools/javac/api/taskListeners/CompileEvent.java index 1c6bf7fc34c..097ef1cef79 100644 --- a/langtools/test/tools/javac/api/taskListeners/CompileEvent.java +++ b/langtools/test/tools/javac/api/taskListeners/CompileEvent.java @@ -73,18 +73,19 @@ public class CompileEvent { assertOutput(out.toString()); JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); - Iterable testFileObjects = fm.getJavaFileObjects(test); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { + Iterable testFileObjects = fm.getJavaFileObjects(test); - //test events fired to listeners registered from plugins - //when starting compiler using JavaCompiler.getTask(...).call - List options = - Arrays.asList("-Xplugin:compile-event", "-processorpath", testClasses); - out = new StringWriter(); - boolean compResult = comp.getTask(out, null, null, options, null, testFileObjects).call(); - if (!compResult) - throw new AssertionError("Compilation failed unexpectedly."); - assertOutput(out.toString()); + //test events fired to listeners registered from plugins + //when starting compiler using JavaCompiler.getTask(...).call + List options = + Arrays.asList("-Xplugin:compile-event", "-processorpath", testClasses); + out = new StringWriter(); + boolean compResult = comp.getTask(out, null, null, options, null, testFileObjects).call(); + if (!compResult) + throw new AssertionError("Compilation failed unexpectedly."); + assertOutput(out.toString()); + } } void assertOutput(String found) { diff --git a/langtools/test/tools/javac/api/taskListeners/EventsBalancedTest.java b/langtools/test/tools/javac/api/taskListeners/EventsBalancedTest.java index 20a8a656bb9..b4b2f05ad4e 100644 --- a/langtools/test/tools/javac/api/taskListeners/EventsBalancedTest.java +++ b/langtools/test/tools/javac/api/taskListeners/EventsBalancedTest.java @@ -44,7 +44,12 @@ public class EventsBalancedTest { StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); public static void main(String... args) throws IOException { - new EventsBalancedTest().test(); + EventsBalancedTest t = new EventsBalancedTest(); + try { + t.test(); + } finally { + t.fm.close(); + } } void test() throws IOException { diff --git a/langtools/test/tools/javac/api/taskListeners/TestSimpleAddRemove.java b/langtools/test/tools/javac/api/taskListeners/TestSimpleAddRemove.java index e45aeb1884f..43259e1a11d 100644 --- a/langtools/test/tools/javac/api/taskListeners/TestSimpleAddRemove.java +++ b/langtools/test/tools/javac/api/taskListeners/TestSimpleAddRemove.java @@ -203,7 +203,12 @@ public class TestSimpleAddRemove { } public static void main(String... args) throws Exception { - new TestSimpleAddRemove().run(); + TestSimpleAddRemove t = new TestSimpleAddRemove(); + try { + t.run(); + } finally { + t.fm.close(); + } } JavacTool tool = (JavacTool) ToolProvider.getSystemJavaCompiler(); diff --git a/langtools/test/tools/javac/cast/intersection/IntersectionTypeParserTest.java b/langtools/test/tools/javac/cast/intersection/IntersectionTypeParserTest.java index d3fefafdfa6..1a579bedc24 100644 --- a/langtools/test/tools/javac/cast/intersection/IntersectionTypeParserTest.java +++ b/langtools/test/tools/javac/cast/intersection/IntersectionTypeParserTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -104,35 +104,36 @@ public class IntersectionTypeParserTest { public static void main(String... args) throws Exception { //create default shared JavaCompiler - reused across multiple compilations JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { - for (CastKind ck : CastKind.values()) { - for (TypeKind t1 : TypeKind.values()) { - for (ArrayKind ak1 : ArrayKind.values()) { - Type typ1 = new Type(t1, ak1); - if (ck.nBounds == 1) { - new IntersectionTypeParserTest(ck, typ1).run(comp, fm); - continue; - } - for (TypeKind t2 : TypeKind.values()) { - for (ArrayKind ak2 : ArrayKind.values()) { - Type typ2 = new Type(t2, ak2); - if (ck.nBounds == 2) { - new IntersectionTypeParserTest(ck, typ1, typ2).run(comp, fm); - continue; - } - for (TypeKind t3 : TypeKind.values()) { - for (ArrayKind ak3 : ArrayKind.values()) { - Type typ3 = new Type(t3, ak3); - new IntersectionTypeParserTest(ck, typ1, typ2, typ3).run(comp, fm); + for (CastKind ck : CastKind.values()) { + for (TypeKind t1 : TypeKind.values()) { + for (ArrayKind ak1 : ArrayKind.values()) { + Type typ1 = new Type(t1, ak1); + if (ck.nBounds == 1) { + new IntersectionTypeParserTest(ck, typ1).run(comp, fm); + continue; + } + for (TypeKind t2 : TypeKind.values()) { + for (ArrayKind ak2 : ArrayKind.values()) { + Type typ2 = new Type(t2, ak2); + if (ck.nBounds == 2) { + new IntersectionTypeParserTest(ck, typ1, typ2).run(comp, fm); + continue; + } + for (TypeKind t3 : TypeKind.values()) { + for (ArrayKind ak3 : ArrayKind.values()) { + Type typ3 = new Type(t3, ak3); + new IntersectionTypeParserTest(ck, typ1, typ2, typ3).run(comp, fm); + } } } } } } } + System.out.println("Total check executed: " + checkCount); } - System.out.println("Total check executed: " + checkCount); } CastKind ck; diff --git a/langtools/test/tools/javac/classreader/T7031108.java b/langtools/test/tools/javac/classreader/T7031108.java index 14b308a0cc9..182ce1892ed 100644 --- a/langtools/test/tools/javac/classreader/T7031108.java +++ b/langtools/test/tools/javac/classreader/T7031108.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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,39 +68,40 @@ public class T7031108 extends JavacTestingAbstractProcessor { void run() throws Exception { JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { - // step 1: compile test classes - File cwd = new File("."); - fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(cwd)); - compile(comp, fm, null, null, pC); + // step 1: compile test classes + File cwd = new File("."); + fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(cwd)); + compile(comp, fm, null, null, pC); - // step 2: verify functioning of processor - fm.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, - fm.getLocation(StandardLocation.CLASS_PATH)); - fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(cwd)); - compile(comp, fm, null, getClass().getName(), dummy); + // step 2: verify functioning of processor + fm.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, + fm.getLocation(StandardLocation.CLASS_PATH)); + fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(cwd)); + compile(comp, fm, null, getClass().getName(), dummy); - File pC_class = new File(new File("p"), "C.class"); - pC_class.delete(); + File pC_class = new File(new File("p"), "C.class"); + pC_class.delete(); - DiagnosticCollector dc = new DiagnosticCollector(); - compile(comp, fm, dc, getClass().getName(), dummy); - List> diags =dc.getDiagnostics(); + DiagnosticCollector dc = new DiagnosticCollector(); + compile(comp, fm, dc, getClass().getName(), dummy); + List> diags =dc.getDiagnostics(); - System.err.println(diags); - switch (diags.size()) { - case 0: - throw new Exception("no diagnostics received"); - case 1: - String code = diags.get(0).getCode(); - String expect = "compiler.err.proc.cant.access.1"; - if (!expect.equals(code)) - throw new Exception("unexpected diag code: " + code - + ", expected: " + expect); - break; - default: - throw new Exception("unexpected diags received"); + System.err.println(diags); + switch (diags.size()) { + case 0: + throw new Exception("no diagnostics received"); + case 1: + String code = diags.get(0).getCode(); + String expect = "compiler.err.proc.cant.access.1"; + if (!expect.equals(code)) + throw new Exception("unexpected diag code: " + code + + ", expected: " + expect); + break; + default: + throw new Exception("unexpected diags received"); + } } } diff --git a/langtools/test/tools/javac/defaultMethods/DefaultMethodFlags.java b/langtools/test/tools/javac/defaultMethods/DefaultMethodFlags.java index 2aea0e46ea5..e911789339f 100644 --- a/langtools/test/tools/javac/defaultMethods/DefaultMethodFlags.java +++ b/langtools/test/tools/javac/defaultMethods/DefaultMethodFlags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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,31 +54,32 @@ public class DefaultMethodFlags { void checkDefaultMethodFlags() throws IOException { JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); - Iterable fos = - fm.getJavaFileObjectsFromFiles( - Arrays.asList(new File( - System.getProperty("test.src"), - this.getClass().getSimpleName() + ".java"))); - JavacTask task = (JavacTask) c.getTask(null, fm, null, null, null, fos); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + Iterable fos = + fm.getJavaFileObjectsFromFiles( + Arrays.asList(new File( + System.getProperty("test.src"), + this.getClass().getSimpleName() + ".java"))); + JavacTask task = (JavacTask) c.getTask(null, fm, null, null, null, fos); - task.addTaskListener(new TaskListener() { + task.addTaskListener(new TaskListener() { - @Override - public void started(TaskEvent e) {} + @Override + public void started(TaskEvent e) {} - @Override - public void finished(TaskEvent e) { - if (e.getKind() == TaskEvent.Kind.ANALYZE) { - TypeElement te = e.getTypeElement(); - if (te.getSimpleName().toString().equals("I")) { - checkDefaultInterface(te); + @Override + public void finished(TaskEvent e) { + if (e.getKind() == TaskEvent.Kind.ANALYZE) { + TypeElement te = e.getTypeElement(); + if (te.getSimpleName().toString().equals("I")) { + checkDefaultInterface(te); + } } } - } - }); + }); - task.analyze(); + task.analyze(); + } } void checkDefaultInterface(TypeElement te) { diff --git a/langtools/test/tools/javac/defaultMethods/static/hiding/InterfaceMethodHidingTest.java b/langtools/test/tools/javac/defaultMethods/static/hiding/InterfaceMethodHidingTest.java index 52f912b6ecb..3aeb6e35ded 100644 --- a/langtools/test/tools/javac/defaultMethods/static/hiding/InterfaceMethodHidingTest.java +++ b/langtools/test/tools/javac/defaultMethods/static/hiding/InterfaceMethodHidingTest.java @@ -123,18 +123,19 @@ public class InterfaceMethodHidingTest { //create default shared JavaCompiler - reused across multiple compilations JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { - for (MethodKind mk1 : MethodKind.values()) { - for (SignatureKind sk1 : SignatureKind.values()) { - for (BodyExpr be1 : BodyExpr.values()) { - for (MethodKind mk2 : MethodKind.values()) { - for (SignatureKind sk2 : SignatureKind.values()) { - for (BodyExpr be2 : BodyExpr.values()) { - for (MethodKind mk3 : MethodKind.values()) { - for (SignatureKind sk3 : SignatureKind.values()) { - for (BodyExpr be3 : BodyExpr.values()) { - new InterfaceMethodHidingTest(mk1, mk2, mk3, sk1, sk2, sk3, be1, be2, be3).run(comp, fm); + for (MethodKind mk1 : MethodKind.values()) { + for (SignatureKind sk1 : SignatureKind.values()) { + for (BodyExpr be1 : BodyExpr.values()) { + for (MethodKind mk2 : MethodKind.values()) { + for (SignatureKind sk2 : SignatureKind.values()) { + for (BodyExpr be2 : BodyExpr.values()) { + for (MethodKind mk3 : MethodKind.values()) { + for (SignatureKind sk3 : SignatureKind.values()) { + for (BodyExpr be3 : BodyExpr.values()) { + new InterfaceMethodHidingTest(mk1, mk2, mk3, sk1, sk2, sk3, be1, be2, be3).run(comp, fm); + } } } } @@ -143,8 +144,8 @@ public class InterfaceMethodHidingTest { } } } + System.out.println("Total check executed: " + checkCount); } - System.out.println("Total check executed: " + checkCount); } MethodKind mk1, mk2, mk3; diff --git a/langtools/test/tools/javac/defaultMethods/syntax/TestDefaultMethodsSyntax.java b/langtools/test/tools/javac/defaultMethods/syntax/TestDefaultMethodsSyntax.java index 122e7c7e6eb..8a3a294bc84 100644 --- a/langtools/test/tools/javac/defaultMethods/syntax/TestDefaultMethodsSyntax.java +++ b/langtools/test/tools/javac/defaultMethods/syntax/TestDefaultMethodsSyntax.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -188,20 +188,21 @@ public class TestDefaultMethodsSyntax { //create default shared JavaCompiler - reused across multiple compilations JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { - for (VersionKind vk : VersionKind.values()) { - for (EnclosingKind ek : EnclosingKind.values()) { - for (MethodKind mk : MethodKind.values()) { - for (ModifierKind modk1 : ModifierKind.values()) { - for (ModifierKind modk2 : ModifierKind.values()) { - new TestDefaultMethodsSyntax(vk, ek, mk, modk1, modk2).run(comp, fm); + for (VersionKind vk : VersionKind.values()) { + for (EnclosingKind ek : EnclosingKind.values()) { + for (MethodKind mk : MethodKind.values()) { + for (ModifierKind modk1 : ModifierKind.values()) { + for (ModifierKind modk2 : ModifierKind.values()) { + new TestDefaultMethodsSyntax(vk, ek, mk, modk1, modk2).run(comp, fm); + } } } } } + System.out.println("Total check executed: " + checkCount); } - System.out.println("Total check executed: " + checkCount); } VersionKind vk; diff --git a/langtools/test/tools/javac/diags/CheckResourceKeys.java b/langtools/test/tools/javac/diags/CheckResourceKeys.java index 5f7f5c3ea41..f1d439243a1 100644 --- a/langtools/test/tools/javac/diags/CheckResourceKeys.java +++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java @@ -313,27 +313,28 @@ public class CheckResourceKeys { Set getCodeStrings() throws IOException { Set results = new TreeSet(); JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - JavaFileManager fm = c.getStandardFileManager(null, null, null); - JavaFileManager.Location javacLoc = findJavacLocation(fm); - String[] pkgs = { - "javax.annotation.processing", - "javax.lang.model", - "javax.tools", - "com.sun.source", - "com.sun.tools.javac" - }; - for (String pkg: pkgs) { - for (JavaFileObject fo: fm.list(javacLoc, - pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) { - String name = fo.getName(); - // ignore resource files, and files which are not really part of javac - if (name.matches(".*resources.[A-Za-z_0-9]+\\.class.*") - || name.matches(".*CreateSymbols\\.class.*")) - continue; - scan(fo, results); + try (JavaFileManager fm = c.getStandardFileManager(null, null, null)) { + JavaFileManager.Location javacLoc = findJavacLocation(fm); + String[] pkgs = { + "javax.annotation.processing", + "javax.lang.model", + "javax.tools", + "com.sun.source", + "com.sun.tools.javac" + }; + for (String pkg: pkgs) { + for (JavaFileObject fo: fm.list(javacLoc, + pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) { + String name = fo.getName(); + // ignore resource files, and files which are not really part of javac + if (name.matches(".*resources.[A-Za-z_0-9]+\\.class.*") + || name.matches(".*CreateSymbols\\.class.*")) + continue; + scan(fo, results); + } } + return results; } - return results; } // depending on how the test is run, javac may be on bootclasspath or classpath diff --git a/langtools/test/tools/javac/doclint/DocLintTest.java b/langtools/test/tools/javac/doclint/DocLintTest.java index 7da6e14b214..ec263158d7a 100644 --- a/langtools/test/tools/javac/doclint/DocLintTest.java +++ b/langtools/test/tools/javac/doclint/DocLintTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -109,44 +109,48 @@ public class DocLintTest { void run() throws Exception { javac = ToolProvider.getSystemJavaCompiler(); fm = javac.getStandardFileManager(null, null, null); - fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); - file = new SimpleJavaFileObject(URI.create("Test.java"), JavaFileObject.Kind.SOURCE) { - @Override - public CharSequence getCharContent(boolean ignoreEncoding) { - return code; - } - }; + try { + fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); + file = new SimpleJavaFileObject(URI.create("Test.java"), JavaFileObject.Kind.SOURCE) { + @Override + public CharSequence getCharContent(boolean ignoreEncoding) { + return code; + } + }; - test(Collections.emptyList(), - Main.Result.OK, - EnumSet.noneOf(Message.class)); + test(Collections.emptyList(), + Main.Result.OK, + EnumSet.noneOf(Message.class)); - test(Arrays.asList("-Xdoclint:none"), - Main.Result.OK, - EnumSet.noneOf(Message.class)); + test(Arrays.asList("-Xdoclint:none"), + Main.Result.OK, + EnumSet.noneOf(Message.class)); - test(Arrays.asList(rawDiags, "-Xdoclint"), - Main.Result.ERROR, - EnumSet.of(Message.DL_ERR6, Message.DL_ERR9, Message.DL_WRN12)); + test(Arrays.asList(rawDiags, "-Xdoclint"), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR6, Message.DL_ERR9, Message.DL_WRN12)); - test(Arrays.asList(rawDiags, "-Xdoclint:all/public"), - Main.Result.OK, - EnumSet.of(Message.DL_WRN12)); + test(Arrays.asList(rawDiags, "-Xdoclint:all/public"), + Main.Result.OK, + EnumSet.of(Message.DL_WRN12)); - test(Arrays.asList(rawDiags, "-Xdoclint:syntax"), - Main.Result.ERROR, - EnumSet.of(Message.DL_ERR6, Message.DL_WRN12)); + test(Arrays.asList(rawDiags, "-Xdoclint:syntax"), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR6, Message.DL_WRN12)); - test(Arrays.asList(rawDiags, "-Xdoclint:reference"), - Main.Result.ERROR, - EnumSet.of(Message.DL_ERR9)); + test(Arrays.asList(rawDiags, "-Xdoclint:reference"), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR9)); - test(Arrays.asList(rawDiags, "-Xdoclint:badarg"), - Main.Result.CMDERR, - EnumSet.of(Message.OPT_BADARG)); + test(Arrays.asList(rawDiags, "-Xdoclint:badarg"), + Main.Result.CMDERR, + EnumSet.of(Message.OPT_BADARG)); - if (errors > 0) - throw new Exception(errors + " errors occurred"); + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } finally { + fm.close(); + } } void test(List opts, Main.Result expectResult, Set expectMessages) { diff --git a/langtools/test/tools/javac/doctree/DocTreePathScannerTest.java b/langtools/test/tools/javac/doctree/DocTreePathScannerTest.java index 5261a0a858f..d4f53934a5d 100644 --- a/langtools/test/tools/javac/doctree/DocTreePathScannerTest.java +++ b/langtools/test/tools/javac/doctree/DocTreePathScannerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -66,22 +66,23 @@ public class DocTreePathScannerTest { } JavacTool javac = JavacTool.create(); - StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) { - Iterable fos = fm.getJavaFileObjectsFromFiles(files); + Iterable fos = fm.getJavaFileObjectsFromFiles(files); - JavacTask t = javac.getTask(null, fm, null, null, null, fos); - DocTrees trees = DocTrees.instance(t); + JavacTask t = javac.getTask(null, fm, null, null, null, fos); + DocTrees trees = DocTrees.instance(t); - Iterable units = t.parse(); + Iterable units = t.parse(); - DeclScanner ds = new DeclScanner(trees); - for (CompilationUnitTree unit: units) { - ds.scan(unit, null); + DeclScanner ds = new DeclScanner(trees); + for (CompilationUnitTree unit: units) { + ds.scan(unit, null); + } + + if (errors > 0) + throw new Exception(errors + " errors occurred"); } - - if (errors > 0) - throw new Exception(errors + " errors occurred"); } void error(String msg) { diff --git a/langtools/test/tools/javac/doctree/SimpleDocTreeVisitorTest.java b/langtools/test/tools/javac/doctree/SimpleDocTreeVisitorTest.java index 8b0bf810012..8e2ab665be8 100644 --- a/langtools/test/tools/javac/doctree/SimpleDocTreeVisitorTest.java +++ b/langtools/test/tools/javac/doctree/SimpleDocTreeVisitorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -66,28 +66,29 @@ public class SimpleDocTreeVisitorTest { } JavacTool javac = JavacTool.create(); - StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) { - Iterable fos = fm.getJavaFileObjectsFromFiles(files); + Iterable fos = fm.getJavaFileObjectsFromFiles(files); - JavacTask t = javac.getTask(null, fm, null, null, null, fos); - DocTrees trees = DocTrees.instance(t); + JavacTask t = javac.getTask(null, fm, null, null, null, fos); + DocTrees trees = DocTrees.instance(t); - Iterable units = t.parse(); + Iterable units = t.parse(); - Set found = EnumSet.noneOf(DocTree.Kind.class); - DeclScanner ds = new DeclScanner(trees, found); - for (CompilationUnitTree unit: units) { - ds.scan(unit, null); + Set found = EnumSet.noneOf(DocTree.Kind.class); + DeclScanner ds = new DeclScanner(trees, found); + for (CompilationUnitTree unit: units) { + ds.scan(unit, null); + } + + for (DocTree.Kind k: DocTree.Kind.values()) { + if (!found.contains(k) && k != DocTree.Kind.OTHER) + error("not found: " + k); + } + + if (errors > 0) + throw new Exception(errors + " errors occurred"); } - - for (DocTree.Kind k: DocTree.Kind.values()) { - if (!found.contains(k) && k != DocTree.Kind.OTHER) - error("not found: " + k); - } - - if (errors > 0) - throw new Exception(errors + " errors occurred"); } void error(String msg) { diff --git a/langtools/test/tools/javac/file/T7068451.java b/langtools/test/tools/javac/file/T7068451.java index ab0d9036a38..c56cccfe1c1 100644 --- a/langtools/test/tools/javac/file/T7068451.java +++ b/langtools/test/tools/javac/file/T7068451.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -47,6 +47,7 @@ import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic.Kind; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; +import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import javax.tools.ToolProvider; @@ -75,34 +76,36 @@ public class T7068451 { System.err.println("FIRST compilation"); System.err.println(); - CompilationTask task = compiler.getTask(null, null, null, opts, null, - compiler.getStandardFileManager(null, null, null).getJavaFileObjects(input)); - task.setProcessors(Collections.singleton(new Proc("first"))); - check("compilation", task.call()); + try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { + CompilationTask task = compiler.getTask(null, fm, null, opts, null, + fm.getJavaFileObjects(input)); + task.setProcessors(Collections.singleton(new Proc("first"))); + check("compilation", task.call()); - writeFile(tmp, "X.java", "package p; class X { { p.C.second(); } }"); + writeFile(tmp, "X.java", "package p; class X { { p.C.second(); } }"); - //Thread.sleep(2000); + //Thread.sleep(2000); - System.err.println(); - System.err.println("SECOND compilation"); - System.err.println(); + System.err.println(); + System.err.println("SECOND compilation"); + System.err.println(); - task = compiler.getTask(null, null, null, opts, null, - compiler.getStandardFileManager(null, null, null).getJavaFileObjects(input)); - task.setProcessors(Collections.singleton(new Proc("second"))); - check("compilation", task.call()); + task = compiler.getTask(null, fm, null, opts, null, + fm.getJavaFileObjects(input)); + task.setProcessors(Collections.singleton(new Proc("second"))); + check("compilation", task.call()); - //Thread.sleep(2000); + //Thread.sleep(2000); - System.err.println(); - System.err.println("SECOND compilation, REPEATED"); - System.err.println(); + System.err.println(); + System.err.println("SECOND compilation, REPEATED"); + System.err.println(); - task = compiler.getTask(null, null, null, opts, null, - compiler.getStandardFileManager(null, null, null).getJavaFileObjects(input)); - task.setProcessors(Collections.singleton(new Proc("second"))); - check("compilation", task.call()); + task = compiler.getTask(null, fm, null, opts, null, + fm.getJavaFileObjects(input)); + task.setProcessors(Collections.singleton(new Proc("second"))); + check("compilation", task.call()); + } } void check(String msg, boolean ok) { diff --git a/langtools/test/tools/javac/flow/LVTHarness.java b/langtools/test/tools/javac/flow/LVTHarness.java index 33ab0441748..a9e31f6efc0 100644 --- a/langtools/test/tools/javac/flow/LVTHarness.java +++ b/langtools/test/tools/javac/flow/LVTHarness.java @@ -76,18 +76,21 @@ public class LVTHarness { static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); public static void main(String[] args) throws Exception { + try { + String testDir = System.getProperty("test.src"); + fm.setLocation(SOURCE_PATH, Arrays.asList(new File(testDir, "tests"))); - String testDir = System.getProperty("test.src"); - fm.setLocation(SOURCE_PATH, Arrays.asList(new File(testDir, "tests"))); + // Make sure classes are written to scratch dir. + fm.setLocation(CLASS_OUTPUT, Arrays.asList(new File("."))); - // Make sure classes are written to scratch dir. - fm.setLocation(CLASS_OUTPUT, Arrays.asList(new File("."))); - - for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(SOURCE), true)) { - new LVTHarness(jfo).check(); - } - if (nerrors > 0) { - throw new AssertionError("Errors were found"); + for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(SOURCE), true)) { + new LVTHarness(jfo).check(); + } + if (nerrors > 0) { + throw new AssertionError("Errors were found"); + } + } finally { + fm.close(); } } diff --git a/langtools/test/tools/javac/generics/bridges/BridgeHarness.java b/langtools/test/tools/javac/generics/bridges/BridgeHarness.java index b4199cf8235..627dd74dc84 100644 --- a/langtools/test/tools/javac/generics/bridges/BridgeHarness.java +++ b/langtools/test/tools/javac/generics/bridges/BridgeHarness.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -70,19 +70,23 @@ public class BridgeHarness { static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); public static void main(String[] args) throws Exception { - //set sourcepath - fm.setLocation(SOURCE_PATH, - Arrays.asList(new File(System.getProperty("test.src"), "tests"))); - //set output (-d) - fm.setLocation(javax.tools.StandardLocation.CLASS_OUTPUT, - Arrays.asList(new File(System.getProperty("user.dir")))); - for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(JavaFileObject.Kind.SOURCE), true)) { - //for each source, compile and check against annotations - new BridgeHarness(jfo).compileAndCheck(); - } - //if there were errors, fail - if (nerrors > 0) { - throw new AssertionError("Errors were found"); + try { + //set sourcepath + fm.setLocation(SOURCE_PATH, + Arrays.asList(new File(System.getProperty("test.src"), "tests"))); + //set output (-d) + fm.setLocation(javax.tools.StandardLocation.CLASS_OUTPUT, + Arrays.asList(new File(System.getProperty("user.dir")))); + for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(JavaFileObject.Kind.SOURCE), true)) { + //for each source, compile and check against annotations + new BridgeHarness(jfo).compileAndCheck(); + } + //if there were errors, fail + if (nerrors > 0) { + throw new AssertionError("Errors were found"); + } + } finally { + fm.close(); } } diff --git a/langtools/test/tools/javac/generics/diamond/7030150/GenericConstructorAndDiamondTest.java b/langtools/test/tools/javac/generics/diamond/7030150/GenericConstructorAndDiamondTest.java index 13a47920edb..f3dee951c25 100644 --- a/langtools/test/tools/javac/generics/diamond/7030150/GenericConstructorAndDiamondTest.java +++ b/langtools/test/tools/javac/generics/diamond/7030150/GenericConstructorAndDiamondTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -150,17 +150,17 @@ public class GenericConstructorAndDiamondTest { //create default shared JavaCompiler - reused across multiple compilations JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); - - for (BoundKind boundKind : BoundKind.values()) { - for (ConstructorKind constructorKind : ConstructorKind.values()) { - for (TypeArgumentKind declArgKind : TypeArgumentKind.values()) { - for (TypeArgArity arity : TypeArgArity.values()) { - for (TypeArgumentKind useArgKind : TypeArgumentKind.values()) { - for (TypeArgumentKind diamondArgKind : TypeArgumentKind.values()) { - for (ArgumentKind argKind : ArgumentKind.values()) { - new GenericConstructorAndDiamondTest(boundKind, constructorKind, - declArgKind, arity, useArgKind, diamondArgKind, argKind).run(comp, fm); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { + for (BoundKind boundKind : BoundKind.values()) { + for (ConstructorKind constructorKind : ConstructorKind.values()) { + for (TypeArgumentKind declArgKind : TypeArgumentKind.values()) { + for (TypeArgArity arity : TypeArgArity.values()) { + for (TypeArgumentKind useArgKind : TypeArgumentKind.values()) { + for (TypeArgumentKind diamondArgKind : TypeArgumentKind.values()) { + for (ArgumentKind argKind : ArgumentKind.values()) { + new GenericConstructorAndDiamondTest(boundKind, constructorKind, + declArgKind, arity, useArgKind, diamondArgKind, argKind).run(comp, fm); + } } } } diff --git a/langtools/test/tools/javac/generics/diamond/7030687/ParserTest.java b/langtools/test/tools/javac/generics/diamond/7030687/ParserTest.java index cc7dddf0495..b7dd65b5541 100644 --- a/langtools/test/tools/javac/generics/diamond/7030687/ParserTest.java +++ b/langtools/test/tools/javac/generics/diamond/7030687/ParserTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -78,26 +78,27 @@ public class ParserTest { //create default shared JavaCompiler - reused across multiple compilations JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { - for (TypeQualifierArity arity : TypeQualifierArity.values()) { - for (TypeArgumentKind tak1 : TypeArgumentKind.values()) { - if (arity == TypeQualifierArity.ONE) { - new ParserTest(arity, tak1).run(comp, fm); - continue; - } - for (TypeArgumentKind tak2 : TypeArgumentKind.values()) { - if (arity == TypeQualifierArity.TWO) { - new ParserTest(arity, tak1, tak2).run(comp, fm); + for (TypeQualifierArity arity : TypeQualifierArity.values()) { + for (TypeArgumentKind tak1 : TypeArgumentKind.values()) { + if (arity == TypeQualifierArity.ONE) { + new ParserTest(arity, tak1).run(comp, fm); continue; } - for (TypeArgumentKind tak3 : TypeArgumentKind.values()) { - if (arity == TypeQualifierArity.THREE) { - new ParserTest(arity, tak1, tak2, tak3).run(comp, fm); + for (TypeArgumentKind tak2 : TypeArgumentKind.values()) { + if (arity == TypeQualifierArity.TWO) { + new ParserTest(arity, tak1, tak2).run(comp, fm); continue; } - for (TypeArgumentKind tak4 : TypeArgumentKind.values()) { - new ParserTest(arity, tak1, tak2, tak3, tak4).run(comp, fm); + for (TypeArgumentKind tak3 : TypeArgumentKind.values()) { + if (arity == TypeQualifierArity.THREE) { + new ParserTest(arity, tak1, tak2, tak3).run(comp, fm); + continue; + } + for (TypeArgumentKind tak4 : TypeArgumentKind.values()) { + new ParserTest(arity, tak1, tak2, tak3, tak4).run(comp, fm); + } } } } diff --git a/langtools/test/tools/javac/generics/inference/7086601/T7086601b.java b/langtools/test/tools/javac/generics/inference/7086601/T7086601b.java index 64a3c81e740..e14f608bf5f 100644 --- a/langtools/test/tools/javac/generics/inference/7086601/T7086601b.java +++ b/langtools/test/tools/javac/generics/inference/7086601/T7086601b.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -86,18 +86,19 @@ public class T7086601b { //create default shared JavaCompiler - reused across multiple compilations JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { - for (TypeKind a1 : TypeKind.values()) { - for (TypeKind a2 : TypeKind.values()) { - for (TypeKind a3 : TypeKind.values()) { - for (MethodCallKind mck : MethodCallKind.values()) { - new T7086601b(a1, a2, a3, mck).run(comp, fm); + for (TypeKind a1 : TypeKind.values()) { + for (TypeKind a2 : TypeKind.values()) { + for (TypeKind a3 : TypeKind.values()) { + for (MethodCallKind mck : MethodCallKind.values()) { + new T7086601b(a1, a2, a3, mck).run(comp, fm); + } } } } + System.out.println("Total check executed: " + checkCount); } - System.out.println("Total check executed: " + checkCount); } TypeKind a1; diff --git a/langtools/test/tools/javac/lambda/BadLambdaExpr.java b/langtools/test/tools/javac/lambda/BadLambdaExpr.java index 80b342288e2..d981943a517 100644 --- a/langtools/test/tools/javac/lambda/BadLambdaExpr.java +++ b/langtools/test/tools/javac/lambda/BadLambdaExpr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -105,18 +105,19 @@ public class BadLambdaExpr { //create default shared JavaCompiler - reused across multiple compilations JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { - for (ParameterListKind plk : ParameterListKind.values()) { - for (ParameterKind pk : ParameterKind.values()) { - for (ArrowKind ak : ArrowKind.values()) { - for (ExprKind ek : ExprKind.values()) { - new BadLambdaExpr(plk, pk, ak, ek).run(comp, fm); + for (ParameterListKind plk : ParameterListKind.values()) { + for (ParameterKind pk : ParameterKind.values()) { + for (ArrowKind ak : ArrowKind.values()) { + for (ExprKind ek : ExprKind.values()) { + new BadLambdaExpr(plk, pk, ak, ek).run(comp, fm); + } } } } + System.out.println("Total check executed: " + checkCount); } - System.out.println("Total check executed: " + checkCount); } ParameterListKind plk; diff --git a/langtools/test/tools/javac/lambda/TestSelfRef.java b/langtools/test/tools/javac/lambda/TestSelfRef.java index 58ab1426103..e34daff7fc1 100644 --- a/langtools/test/tools/javac/lambda/TestSelfRef.java +++ b/langtools/test/tools/javac/lambda/TestSelfRef.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -114,22 +114,23 @@ public class TestSelfRef { //create default shared JavaCompiler - reused across multiple compilations JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { - for (EnclosingKind ek : EnclosingKind.values()) { - for (SiteKind sk : SiteKind.values()) { - if (sk == SiteKind.STATIC_INIT && ek == EnclosingKind.MEMBER_INNER) - continue; - for (InnerKind ik : InnerKind.values()) { - if (ik != InnerKind.NONE && sk == SiteKind.NONE) - break; - for (RefKind rk : RefKind.values()) { - new TestSelfRef(ek, sk, ik, rk).run(comp, fm); + for (EnclosingKind ek : EnclosingKind.values()) { + for (SiteKind sk : SiteKind.values()) { + if (sk == SiteKind.STATIC_INIT && ek == EnclosingKind.MEMBER_INNER) + continue; + for (InnerKind ik : InnerKind.values()) { + if (ik != InnerKind.NONE && sk == SiteKind.NONE) + break; + for (RefKind rk : RefKind.values()) { + new TestSelfRef(ek, sk, ik, rk).run(comp, fm); + } } } } + System.out.println("Total check executed: " + checkCount); } - System.out.println("Total check executed: " + checkCount); } EnclosingKind ek; diff --git a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java index 4b8ec208d15..ef2defa9271 100644 --- a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java +++ b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java @@ -185,14 +185,15 @@ public class IntersectionTargetTypeTest { public static void main(String... args) throws Exception { //create default shared JavaCompiler - reused across multiple compilations JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { - for (CastInfo cInfo : allCastInfo()) { - for (ExpressionKind ek : ExpressionKind.values()) { - new IntersectionTargetTypeTest(cInfo, ek).run(comp, fm); + for (CastInfo cInfo : allCastInfo()) { + for (ExpressionKind ek : ExpressionKind.values()) { + new IntersectionTargetTypeTest(cInfo, ek).run(comp, fm); + } } + System.out.println("Total check executed: " + checkCount); } - System.out.println("Total check executed: " + checkCount); } static List allCastInfo() { diff --git a/langtools/test/tools/javac/lambda/methodReference/SamConversionComboTest.java b/langtools/test/tools/javac/lambda/methodReference/SamConversionComboTest.java index 0151604c12b..5d51b716385 100644 --- a/langtools/test/tools/javac/lambda/methodReference/SamConversionComboTest.java +++ b/langtools/test/tools/javac/lambda/methodReference/SamConversionComboTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -250,13 +250,17 @@ public class SamConversionComboTest { } public static void main(String[] args) throws Exception { - for(Context ct : Context.values()) { - for (FInterface fi : FInterface.values()) { - for (MethodDef md: MethodDef.values()) { - new SamConversionComboTest(fi, ct, md).test(); + try { + for(Context ct : Context.values()) { + for (FInterface fi : FInterface.values()) { + for (MethodDef md: MethodDef.values()) { + new SamConversionComboTest(fi, ct, md).test(); + } } } + System.out.println("total tests: " + count); + } finally { + fm.close(); } - System.out.println("total tests: " + count); } } diff --git a/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/javac/FDTest.java b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/javac/FDTest.java index 3819221a736..d63f7734dbf 100644 --- a/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/javac/FDTest.java +++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/javac/FDTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -28,6 +28,7 @@ import org.openjdk.tests.shapegen.*; import com.sun.source.util.JavacTask; import com.sun.tools.javac.util.Pair; +import java.io.IOException; import java.net.URI; import java.util.Arrays; import java.util.ArrayList; @@ -41,6 +42,7 @@ import javax.tools.SimpleJavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; +import org.testng.annotations.AfterSuite; import org.testng.annotations.Test; import org.testng.annotations.BeforeSuite; import org.testng.annotations.DataProvider; @@ -70,12 +72,19 @@ public class FDTest { fm = comp.getStandardFileManager(null, null, null); } + @AfterSuite + static void teardown() throws IOException { + fm.close(); + } + public static void main(String[] args) throws Exception { init(); for (Pair fdtest : generateCases()) { runTest(fdtest.fst, fdtest.snd, comp, fm); } + + teardown(); } @Test(dataProvider = "fdCases") diff --git a/langtools/test/tools/javac/nativeHeaders/NativeHeaderTest.java b/langtools/test/tools/javac/nativeHeaders/NativeHeaderTest.java index a14c71e345c..3eb7c005948 100644 --- a/langtools/test/tools/javac/nativeHeaders/NativeHeaderTest.java +++ b/langtools/test/tools/javac/nativeHeaders/NativeHeaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -193,27 +193,30 @@ public class NativeHeaderTest { void run() throws Exception { javac = JavacTool.create(); fm = javac.getStandardFileManager(null, null, null); - - for (RunKind rk: RunKind.values()) { - for (GenKind gk: GenKind.values()) { - for (Method m: getClass().getDeclaredMethods()) { - Annotation a = m.getAnnotation(Test.class); - if (a != null) { - init(rk, gk, m.getName()); - try { - m.invoke(this, new Object[] { rk, gk }); - } catch (InvocationTargetException e) { - Throwable cause = e.getCause(); - throw (cause instanceof Exception) ? ((Exception) cause) : e; + try { + for (RunKind rk: RunKind.values()) { + for (GenKind gk: GenKind.values()) { + for (Method m: getClass().getDeclaredMethods()) { + Annotation a = m.getAnnotation(Test.class); + if (a != null) { + init(rk, gk, m.getName()); + try { + m.invoke(this, new Object[] { rk, gk }); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + throw (cause instanceof Exception) ? ((Exception) cause) : e; + } + System.err.println(); } - System.err.println(); } } } + System.err.println(testCount + " tests" + ((errorCount == 0) ? "" : ", " + errorCount + " errors")); + if (errorCount > 0) + throw new Exception(errorCount + " errors found"); + } finally { + fm.close(); } - System.err.println(testCount + " tests" + ((errorCount == 0) ? "" : ", " + errorCount + " errors")); - if (errorCount > 0) - throw new Exception(errorCount + " errors found"); } /** diff --git a/langtools/test/tools/javac/options/xprefer/XPreferTest.java b/langtools/test/tools/javac/options/xprefer/XPreferTest.java index 3a95718fe36..93d1ae71112 100644 --- a/langtools/test/tools/javac/options/xprefer/XPreferTest.java +++ b/langtools/test/tools/javac/options/xprefer/XPreferTest.java @@ -45,6 +45,7 @@ import java.util.regex.Pattern; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; +import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; @@ -73,27 +74,31 @@ public class XPreferTest { } final static JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); + final static StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); final static File OUTPUT_DIR = new File("out"); public static void main(String... args) throws Exception { + try { + // Initialize test-directories + OUTPUT_DIR.mkdir(); + for (Dir dir : Dir.values()) + dir.file.mkdir(); - // Initialize test-directories - OUTPUT_DIR.mkdir(); - for (Dir dir : Dir.values()) - dir.file.mkdir(); + int testCaseCounter = 0; - int testCaseCounter = 0; + for (List

dirSubset : SubseqIter.subseqsOf(Dir.values())) { - for (List dirSubset : SubseqIter.subseqsOf(Dir.values())) { + if (dirSubset.isEmpty()) + continue; - if (dirSubset.isEmpty()) - continue; - - for (ImplicitOption policy : ImplicitOption.values()) { - for (List dirOrder : PermutationIterator.permutationsOf(dirSubset)) { - new TestCase(dirOrder, policy, testCaseCounter++).run(); + for (ImplicitOption policy : ImplicitOption.values()) { + for (List dirOrder : PermutationIterator.permutationsOf(dirSubset)) { + new TestCase(dirOrder, policy, testCaseCounter++).run(); + } } } + } finally { + fm.close(); } } @@ -234,8 +239,8 @@ public class XPreferTest { if(dir == Dir.SOURCE_PATH) return src; // ...otherwise compile into a ".class". - CompilationTask task = comp.getTask(null, null, null, null, null, - comp.getStandardFileManager(null, null, null).getJavaFileObjects(src)); + CompilationTask task = comp.getTask(null, fm, null, null, null, + fm.getJavaFileObjects(src)); File dest = new File(dir.file, classId + ".class"); if(!task.call() || !dest.exists()) throw new RuntimeException("Compilation failure."); diff --git a/langtools/test/tools/javac/plugin/showtype/Test.java b/langtools/test/tools/javac/plugin/showtype/Test.java index b1a3b596571..177eb394d2e 100644 --- a/langtools/test/tools/javac/plugin/showtype/Test.java +++ b/langtools/test/tools/javac/plugin/showtype/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -71,21 +71,25 @@ public class Test { } void run() throws Exception { - // compile the plugin explicitly, to a non-standard directory - // so that we don't find it on the wrong path by accident - pluginClasses.mkdirs(); - compile("-d", pluginClasses.getPath(), pluginSrc.getPath()); - writeFile(new File(pluginClasses, "META-INF/services/com.sun.source.util.Plugin"), - "ShowTypePlugin\n"); - jar("cf", pluginJar.getPath(), "-C", pluginClasses.getPath(), "."); + try { + // compile the plugin explicitly, to a non-standard directory + // so that we don't find it on the wrong path by accident + pluginClasses.mkdirs(); + compile("-d", pluginClasses.getPath(), pluginSrc.getPath()); + writeFile(new File(pluginClasses, "META-INF/services/com.sun.source.util.Plugin"), + "ShowTypePlugin\n"); + jar("cf", pluginJar.getPath(), "-C", pluginClasses.getPath(), "."); - testCommandLine("-Xplugin:showtype", ref1); - testCommandLine("-Xplugin:showtype PI", ref2); - testAPI("-Xplugin:showtype", ref1); - testAPI("-Xplugin:showtype PI", ref2); + testCommandLine("-Xplugin:showtype", ref1); + testCommandLine("-Xplugin:showtype PI", ref2); + testAPI("-Xplugin:showtype", ref1); + testAPI("-Xplugin:showtype PI", ref2); - if (errors > 0) - throw new Exception(errors + " errors occurred"); + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } finally { + fm.close(); + } } void testAPI(String opt, List ref) throws Exception { diff --git a/langtools/test/tools/javac/positions/TreeEndPosTest.java b/langtools/test/tools/javac/positions/TreeEndPosTest.java index e8c6c8689d0..d54c5d4a7d2 100644 --- a/langtools/test/tools/javac/positions/TreeEndPosTest.java +++ b/langtools/test/tools/javac/positions/TreeEndPosTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -137,32 +137,33 @@ public class TreeEndPosTest { File tempDir = new File("."); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); DiagnosticCollector dc = new DiagnosticCollector(); - JavaFileManager javaFileManager = getJavaFileManager(compiler, dc); - List options = new ArrayList<>(); - options.add("-cp"); - options.add(tempDir.getPath()); - options.add("-d"); - options.add(tempDir.getPath()); - options.add("-XDshouldStopPolicy=GENERATE"); + try (JavaFileManager javaFileManager = getJavaFileManager(compiler, dc)) { + List options = new ArrayList<>(); + options.add("-cp"); + options.add(tempDir.getPath()); + options.add("-d"); + options.add(tempDir.getPath()); + options.add("-XDshouldStopPolicy=GENERATE"); - List sources = new ArrayList<>(); - sources.add(src); - JavaCompiler.CompilationTask task = - compiler.getTask(writer, javaFileManager, - dc, options, null, - sources); - task.call(); - for (Diagnostic diagnostic : (List) dc.getDiagnostics()) { - long actualStart = diagnostic.getStartPosition(); - long actualEnd = diagnostic.getEndPosition(); - System.out.println("Source: " + src.source); - System.out.println("Diagnostic: " + diagnostic); - System.out.print("Start position: Expected: " + src.startPos); - System.out.println(", Actual: " + actualStart); - System.out.print("End position: Expected: " + src.endPos); - System.out.println(", Actual: " + actualEnd); - if (src.startPos != actualStart || src.endPos != actualEnd) { - throw new RuntimeException("error: trees don't match"); + List sources = new ArrayList<>(); + sources.add(src); + JavaCompiler.CompilationTask task = + compiler.getTask(writer, javaFileManager, + dc, options, null, + sources); + task.call(); + for (Diagnostic diagnostic : (List) dc.getDiagnostics()) { + long actualStart = diagnostic.getStartPosition(); + long actualEnd = diagnostic.getEndPosition(); + System.out.println("Source: " + src.source); + System.out.println("Diagnostic: " + diagnostic); + System.out.print("Start position: Expected: " + src.startPos); + System.out.println(", Actual: " + actualStart); + System.out.print("End position: Expected: " + src.endPos); + System.out.println(", Actual: " + actualEnd); + if (src.startPos != actualStart || src.endPos != actualEnd) { + throw new RuntimeException("error: trees don't match"); + } } } } diff --git a/langtools/test/tools/javac/processing/6348193/T6348193.java b/langtools/test/tools/javac/processing/6348193/T6348193.java index 76bd491b45b..1a631b20a08 100644 --- a/langtools/test/tools/javac/processing/6348193/T6348193.java +++ b/langtools/test/tools/javac/processing/6348193/T6348193.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -85,35 +85,36 @@ public class T6348193 extends AbstractProcessor MyDiagListener dl = new MyDiagListener(); PrintWriter out = new PrintWriter(System.err, true); - StandardJavaFileManager fm = t.getStandardFileManager(dl, null, null); - File file = new File(System.getProperty("test.src"), myName+".java"); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(file)); - boolean ok = t.getTask(out, null, dl, args, null, files).call(); + try (StandardJavaFileManager fm = t.getStandardFileManager(dl, null, null)) { + File file = new File(System.getProperty("test.src"), myName+".java"); + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(file)); + boolean ok = t.getTask(out, null, dl, args, null, files).call(); - if (config == NoGoodBad.GOOD || proc == NoYes.YES) { - if (secMgr == NoYes.YES) { - if (dl.last == null) - throw new AssertionError("Security manager installed, and processors present, " - + " but no diagnostic received"); + if (config == NoGoodBad.GOOD || proc == NoYes.YES) { + if (secMgr == NoYes.YES) { + if (dl.last == null) + throw new AssertionError("Security manager installed, and processors present, " + + " but no diagnostic received"); + } + else { + if (!processed.exists()) + throw new AssertionError("No security manager installed, and processors present, " + + " but no processing occurred"); + } + } + else if (config == NoGoodBad.BAD) { + // TODO: should verify that no compiler crash occurred + // needs revised JSR199 spec } else { - if (!processed.exists()) - throw new AssertionError("No security manager installed, and processors present, " - + " but no processing occurred"); + if (processed.exists()) + throw new AssertionError("No processors present, but processing occurred!"); } - } - else if (config == NoGoodBad.BAD) { - // TODO: should verify that no compiler crash occurred - // needs revised JSR199 spec - } - else { - if (processed.exists()) - throw new AssertionError("No processors present, but processing occurred!"); - } - if (verbose) - System.err.println("OK"); + if (verbose) + System.err.println("OK"); + } } // set up or remove a service configuration file diff --git a/langtools/test/tools/javac/processing/6348499/T6348499.java b/langtools/test/tools/javac/processing/6348499/T6348499.java index dadcef23d70..da3c182160d 100644 --- a/langtools/test/tools/javac/processing/6348499/T6348499.java +++ b/langtools/test/tools/javac/processing/6348499/T6348499.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -44,32 +44,33 @@ import com.sun.tools.javac.api.*; public class T6348499 { - public static void main(String... args) { + public static void main(String... args) throws IOException { String testSrc = System.getProperty("test.src", "."); String testClasses = System.getProperty("test.classes"); String testClassPath = System.getProperty("test.class.path", testClasses); String A_java = new File(testSrc, "A.java").getPath(); JavacTool tool = JavacTool.create(); MyDiagListener dl = new MyDiagListener(); - StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java"))); - Iterable opts = Arrays.asList("-proc:only", - "-processor", "A", - "-processorpath", testClassPath); - StringWriter out = new StringWriter(); - JavacTask task = tool.getTask(out, fm, dl, opts, null, files); - task.call(); - String s = out.toString(); - System.err.print(s); - // Expect the following 1 multi-line diagnostic, and no output to log - // error: cannot access A_0 - // bad class file: A_0.class - // illegal start of class file - // Please remove or make sure it appears in the correct subdirectory of the classpath. - System.err.println(dl.count + " diagnostics; " + s.length() + " characters"); - if (dl.count != 1 || s.length() != 0) - throw new AssertionError("unexpected output from compiler"); + try (StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null)) { + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java"))); + Iterable opts = Arrays.asList("-proc:only", + "-processor", "A", + "-processorpath", testClassPath); + StringWriter out = new StringWriter(); + JavacTask task = tool.getTask(out, fm, dl, opts, null, files); + task.call(); + String s = out.toString(); + System.err.print(s); + // Expect the following 1 multi-line diagnostic, and no output to log + // error: cannot access A_0 + // bad class file: A_0.class + // illegal start of class file + // Please remove or make sure it appears in the correct subdirectory of the classpath. + System.err.println(dl.count + " diagnostics; " + s.length() + " characters"); + if (dl.count != 1 || s.length() != 0) + throw new AssertionError("unexpected output from compiler"); + } } static class MyDiagListener implements DiagnosticListener { diff --git a/langtools/test/tools/javac/processing/6378728/T6378728.java b/langtools/test/tools/javac/processing/6378728/T6378728.java index 497fba93269..cb1246e7b83 100644 --- a/langtools/test/tools/javac/processing/6378728/T6378728.java +++ b/langtools/test/tools/javac/processing/6378728/T6378728.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -64,21 +64,22 @@ public class T6378728 { } } - public static void main(String[] args) { + public static void main(String[] args) throws IOException { // Get a compiler tool JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); String srcdir = System.getProperty("test.src"); File source = new File(srcdir, "T6378728.java"); - StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { - CompilationTask task = - compiler.getTask(null, - new ExceptionalFileManager(fm), - null, - Arrays.asList("-proc:only"), - null, - fm.getJavaFileObjectsFromFiles(Arrays.asList(source))); - if (!task.call()) - throw new RuntimeException("Unexpected compilation failure"); + CompilationTask task = + compiler.getTask(null, + new ExceptionalFileManager(fm), + null, + Arrays.asList("-proc:only"), + null, + fm.getJavaFileObjectsFromFiles(Arrays.asList(source))); + if (!task.call()) + throw new RuntimeException("Unexpected compilation failure"); + } } } diff --git a/langtools/test/tools/javac/processing/6414633/T6414633.java b/langtools/test/tools/javac/processing/6414633/T6414633.java index e6ee786f122..0b1447dffa1 100644 --- a/langtools/test/tools/javac/processing/6414633/T6414633.java +++ b/langtools/test/tools/javac/processing/6414633/T6414633.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -40,29 +40,30 @@ import com.sun.source.util.*; import com.sun.tools.javac.api.*; public class T6414633 { - public static void main(String... args) { + public static void main(String... args) throws IOException { String testSrc = System.getProperty("test.src", "."); String testClasses = System.getProperty("test.classes", "."); String testClassPath = System.getProperty("test.class.path", testClasses); JavacTool tool = JavacTool.create(); MyDiagListener dl = new MyDiagListener(); - StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); - try { - fm.setLocation(StandardLocation.CLASS_PATH, pathToFiles(testClassPath)); - } catch (IOException e) { - throw new AssertionError(e); - } - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, A.class.getName()+".java"))); - String[] opts = { "-proc:only", - "-processor", A.class.getName() }; - JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files); - task.call(); + try (StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null)) { + try { + fm.setLocation(StandardLocation.CLASS_PATH, pathToFiles(testClassPath)); + } catch (IOException e) { + throw new AssertionError(e); + } + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, A.class.getName()+".java"))); + String[] opts = { "-proc:only", + "-processor", A.class.getName() }; + JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files); + task.call(); - // two annotations on the same element -- expect 2 diags from the processor - if (dl.diags != 2) - throw new AssertionError(dl.diags + " diagnostics reported"); + // two annotations on the same element -- expect 2 diags from the processor + if (dl.diags != 2) + throw new AssertionError(dl.diags + " diagnostics reported"); + } } private static List pathToFiles(String path) { diff --git a/langtools/test/tools/javac/processing/6430209/T6430209.java b/langtools/test/tools/javac/processing/6430209/T6430209.java index 611819a7600..dba79b34c59 100644 --- a/langtools/test/tools/javac/processing/6430209/T6430209.java +++ b/langtools/test/tools/javac/processing/6430209/T6430209.java @@ -58,22 +58,23 @@ public class T6430209 { String testClassPath = System.getProperty("test.class.path"); JavacTool tool = JavacTool.create(); MyDiagListener dl = new MyDiagListener(); - StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); - fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(new File("."))); - Iterable files = fm.getJavaFileObjectsFromFiles(Arrays.asList( - new File(testSrc, "test0.java"), new File(testSrc, "test1.java"))); - Iterable opts = Arrays.asList("-proc:only", - "-processor", "b6341534", - "-processorpath", testClassPath); - StringWriter out = new StringWriter(); - JavacTask task = tool.getTask(out, fm, dl, opts, null, files); - task.call(); - String s = out.toString(); - System.err.print(s); - // Expect the following 2 diagnostics, and no output to log - System.err.println(dl.count + " diagnostics; " + s.length() + " characters"); - if (dl.count != 2 || s.length() != 0) - throw new AssertionError("unexpected output from compiler"); + try (StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null)) { + fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(new File("."))); + Iterable files = fm.getJavaFileObjectsFromFiles(Arrays.asList( + new File(testSrc, "test0.java"), new File(testSrc, "test1.java"))); + Iterable opts = Arrays.asList("-proc:only", + "-processor", "b6341534", + "-processorpath", testClassPath); + StringWriter out = new StringWriter(); + JavacTask task = tool.getTask(out, fm, dl, opts, null, files); + task.call(); + String s = out.toString(); + System.err.print(s); + // Expect the following 2 diagnostics, and no output to log + System.err.println(dl.count + " diagnostics; " + s.length() + " characters"); + if (dl.count != 2 || s.length() != 0) + throw new AssertionError("unexpected output from compiler"); + } } static class MyDiagListener implements DiagnosticListener { diff --git a/langtools/test/tools/javac/processing/T6439826.java b/langtools/test/tools/javac/processing/T6439826.java index ac484655f37..87d0228396f 100644 --- a/langtools/test/tools/javac/processing/T6439826.java +++ b/langtools/test/tools/javac/processing/T6439826.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -40,28 +40,29 @@ import static javax.lang.model.util.ElementFilter.*; @SupportedAnnotationTypes("*") public class T6439826 extends AbstractProcessor { - public static void main(String... args) { + public static void main(String... args) throws IOException { String testSrc = System.getProperty("test.src", "."); String testClasses = System.getProperty("test.classes"); JavacTool tool = JavacTool.create(); MyDiagListener dl = new MyDiagListener(); - StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); - Iterable files = - fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6439826.class.getName()+".java"))); - Iterable opts = Arrays.asList("-proc:only", - "-processor", "T6439826", - "-processorpath", testClasses); - StringWriter out = new StringWriter(); - JavacTask task = tool.getTask(out, fm, dl, opts, null, files); - task.call(); - String s = out.toString(); - System.err.print(s); - // Expect the following 2 diagnostics, and no output to log - // Foo.java:1: illegal character: \35 - // Foo.java:1: reached end of file while parsing - System.err.println(dl.count + " diagnostics; " + s.length() + " characters"); - if (dl.count != 2 || s.length() != 0) - throw new AssertionError("unexpected output from compiler"); + try (StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null)) { + Iterable files = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6439826.class.getName()+".java"))); + Iterable opts = Arrays.asList("-proc:only", + "-processor", "T6439826", + "-processorpath", testClasses); + StringWriter out = new StringWriter(); + JavacTask task = tool.getTask(out, fm, dl, opts, null, files); + task.call(); + String s = out.toString(); + System.err.print(s); + // Expect the following 2 diagnostics, and no output to log + // Foo.java:1: illegal character: \35 + // Foo.java:1: reached end of file while parsing + System.err.println(dl.count + " diagnostics; " + s.length() + " characters"); + if (dl.count != 2 || s.length() != 0) + throw new AssertionError("unexpected output from compiler"); + } } public boolean process(Set annotations, diff --git a/langtools/test/tools/javac/processing/errors/TestSuppression.java b/langtools/test/tools/javac/processing/errors/TestSuppression.java index b6c06f042ce..6e60e4b2d5a 100644 --- a/langtools/test/tools/javac/processing/errors/TestSuppression.java +++ b/langtools/test/tools/javac/processing/errors/TestSuppression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -100,41 +100,42 @@ public class TestSuppression { DiagListener dl = new DiagListener(); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); - fm.setLocation(StandardLocation.CLASS_PATH, - Arrays.asList(classesDir, new File(System.getProperty("test.classes")))); - fm.setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(classesDir)); - fm.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(gensrcDir)); - List args = new ArrayList(); -// args.add("-XprintProcessorInfo"); - args.add("-XprintRounds"); - args.add("-Agen=" + gen); - if (wk == WarningKind.YES) - args.add("-Xlint:serial"); - Iterable files = fm.getJavaFileObjects(x); + try (StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null)) { + fm.setLocation(StandardLocation.CLASS_PATH, + Arrays.asList(classesDir, new File(System.getProperty("test.classes")))); + fm.setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(classesDir)); + fm.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(gensrcDir)); + List args = new ArrayList(); + // args.add("-XprintProcessorInfo"); + args.add("-XprintRounds"); + args.add("-Agen=" + gen); + if (wk == WarningKind.YES) + args.add("-Xlint:serial"); + Iterable files = fm.getJavaFileObjects(x); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - JavacTask task = tool.getTask(pw, fm, dl, args, null, files); - task.setProcessors(Arrays.asList(new AnnoProc())); - boolean ok = task.call(); - pw.close(); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + JavacTask task = tool.getTask(pw, fm, dl, args, null, files); + task.setProcessors(Arrays.asList(new AnnoProc())); + boolean ok = task.call(); + pw.close(); - System.err.println("ok:" + ok + " diags:" + dl.counts); - if (sw.toString().length() > 0) { - System.err.println("output:\n" + sw.toString()); - } - - for (Diagnostic.Kind dk: Diagnostic.Kind.values()) { - Integer v = dl.counts.get(dk); - int found = (v == null) ? 0 : v; - int expect = (dk == Diagnostic.Kind.WARNING && wk == WarningKind.YES) ? gen : 0; - if (found != expect) { - error("Unexpected value for " + dk + ": expected: " + expect + " found: " + found); + System.err.println("ok:" + ok + " diags:" + dl.counts); + if (sw.toString().length() > 0) { + System.err.println("output:\n" + sw.toString()); } - } - System.err.println(); + for (Diagnostic.Kind dk: Diagnostic.Kind.values()) { + Integer v = dl.counts.get(dk); + int found = (v == null) ? 0 : v; + int expect = (dk == Diagnostic.Kind.WARNING && wk == WarningKind.YES) ? gen : 0; + if (found != expect) { + error("Unexpected value for " + dk + ": expected: " + expect + " found: " + found); + } + } + + System.err.println(); + } } File createDir(File parent, String name) { diff --git a/langtools/test/tools/javac/processing/loader/testClose/TestClose.java b/langtools/test/tools/javac/processing/loader/testClose/TestClose.java index 4128a07140e..597a8609a18 100644 --- a/langtools/test/tools/javac/processing/loader/testClose/TestClose.java +++ b/langtools/test/tools/javac/processing/loader/testClose/TestClose.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -117,50 +117,51 @@ public class TestClose implements TaskListener { void run() throws IOException { JavacTool tool = (JavacTool) ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { - File classes = new File("classes"); - classes.mkdirs(); - File extraClasses = new File("extraClasses"); - extraClasses.mkdirs(); + File classes = new File("classes"); + classes.mkdirs(); + File extraClasses = new File("extraClasses"); + extraClasses.mkdirs(); - System.out.println("compiling classes to extraClasses"); - { // setup class in extraClasses - fm.setLocation(StandardLocation.CLASS_OUTPUT, - Collections.singleton(extraClasses)); - List files = Arrays.asList( - new MemFile("AnnoProc.java", annoProc), - new MemFile("Callback.java", callback)); - JavacTask task = tool.getTask(null, fm, null, null, null, files); - check(task.call()); - } - - System.out.println("compiling dummy to classes with anno processor"); - { // use that class in a TaskListener after processing has completed - PrintStream prev = System.out; - String out; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (PrintStream ps = new PrintStream(baos)) { - System.setOut(ps); - File testClasses = new File(System.getProperty("test.classes")); + System.out.println("compiling classes to extraClasses"); + { // setup class in extraClasses fm.setLocation(StandardLocation.CLASS_OUTPUT, - Collections.singleton(classes)); - fm.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, - Arrays.asList(extraClasses, testClasses)); + Collections.singleton(extraClasses)); List files = Arrays.asList( - new MemFile("my://dummy", "class Dummy { }")); - List options = Arrays.asList("-processor", "AnnoProc"); - JavacTask task = tool.getTask(null, fm, null, options, null, files); - task.setTaskListener(this); + new MemFile("AnnoProc.java", annoProc), + new MemFile("Callback.java", callback)); + JavacTask task = tool.getTask(null, fm, null, null, null, files); check(task.call()); - } finally { - System.setOut(prev); - out = baos.toString(); - if (!out.isEmpty()) - System.out.println(out); } - check(out.contains("AnnoProc$1: run()")); - check(out.contains("Callback: run()")); + + System.out.println("compiling dummy to classes with anno processor"); + { // use that class in a TaskListener after processing has completed + PrintStream prev = System.out; + String out; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (PrintStream ps = new PrintStream(baos)) { + System.setOut(ps); + File testClasses = new File(System.getProperty("test.classes")); + fm.setLocation(StandardLocation.CLASS_OUTPUT, + Collections.singleton(classes)); + fm.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, + Arrays.asList(extraClasses, testClasses)); + List files = Arrays.asList( + new MemFile("my://dummy", "class Dummy { }")); + List options = Arrays.asList("-processor", "AnnoProc"); + JavacTask task = tool.getTask(null, fm, null, options, null, files); + task.setTaskListener(this); + check(task.call()); + } finally { + System.setOut(prev); + out = baos.toString(); + if (!out.isEmpty()) + System.out.println(out); + } + check(out.contains("AnnoProc$1: run()")); + check(out.contains("Callback: run()")); + } } } diff --git a/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java b/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java index cde00eec2a5..9629923e9f5 100644 --- a/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java +++ b/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -64,66 +64,67 @@ public class Main { return; } JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - fm.setLocation(CLASS_PATH, Collections.emptyList()); - JavacTask javac = (JavacTask)tool.getTask(null, fm, null, null, null, null); - Elements elements = javac.getElements(); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + fm.setLocation(CLASS_PATH, Collections.emptyList()); + JavacTask javac = (JavacTask)tool.getTask(null, fm, null, null, null, null); + Elements elements = javac.getElements(); - final Set packages = new LinkedHashSet(); + final Set packages = new LinkedHashSet(); - int nestedClasses = 0; - int classes = 0; + int nestedClasses = 0; + int classes = 0; - for (JavaFileObject file : fm.list(PLATFORM_CLASS_PATH, "", EnumSet.of(CLASS), true)) { - String type = fm.inferBinaryName(PLATFORM_CLASS_PATH, file); - if (type.endsWith("package-info")) - continue; - try { - TypeElement elem = elements.getTypeElement(type); - if (elem == null && type.indexOf('$') > 0) { - nestedClasses++; - type = null; + for (JavaFileObject file : fm.list(PLATFORM_CLASS_PATH, "", EnumSet.of(CLASS), true)) { + String type = fm.inferBinaryName(PLATFORM_CLASS_PATH, file); + if (type.endsWith("package-info")) continue; + try { + TypeElement elem = elements.getTypeElement(type); + if (elem == null && type.indexOf('$') > 0) { + nestedClasses++; + type = null; + continue; + } + classes++; + packages.add(getPackage(elem).getQualifiedName().toString()); + elements.getTypeElement(type).getKind(); // force completion + type = null; + } finally { + if (type != null) + System.err.println("Looking at " + type); } - classes++; - packages.add(getPackage(elem).getQualifiedName().toString()); - elements.getTypeElement(type).getKind(); // force completion - type = null; - } finally { - if (type != null) - System.err.println("Looking at " + type); } - } - javac = null; - elements = null; + javac = null; + elements = null; - javac = (JavacTask)tool.getTask(null, fm, null, null, null, null); - elements = javac.getElements(); + javac = (JavacTask)tool.getTask(null, fm, null, null, null, null); + elements = javac.getElements(); - for (String name : packages) { - PackageElement pe = elements.getPackageElement(name); - for (Element e : pe.getEnclosedElements()) { - e.getSimpleName().getClass(); + for (String name : packages) { + PackageElement pe = elements.getPackageElement(name); + for (Element e : pe.getEnclosedElements()) { + e.getSimpleName().getClass(); + } } + /* + * A few sanity checks based on current values: + * + * packages: 775, classes: 12429 + 5917 + * + * As the platform evolves the numbers are likely to grow + * monotonically but in case somebody gets a clever idea for + * limiting the number of packages exposed, this number might + * drop. So we test low values. + */ + System.out.format("packages: %s, classes: %s + %s%n", + packages.size(), classes, nestedClasses); + if (classes < 9000) + throw new AssertionError("Too few classes in PLATFORM_CLASS_PATH ;-)"); + if (packages.size() < 530) + throw new AssertionError("Too few packages in PLATFORM_CLASS_PATH ;-)"); + if (nestedClasses < 3000) + throw new AssertionError("Too few nested classes in PLATFORM_CLASS_PATH ;-)"); } - /* - * A few sanity checks based on current values: - * - * packages: 775, classes: 12429 + 5917 - * - * As the platform evolves the numbers are likely to grow - * monotonically but in case somebody gets a clever idea for - * limiting the number of packages exposed, this number might - * drop. So we test low values. - */ - System.out.format("packages: %s, classes: %s + %s%n", - packages.size(), classes, nestedClasses); - if (classes < 9000) - throw new AssertionError("Too few classes in PLATFORM_CLASS_PATH ;-)"); - if (packages.size() < 530) - throw new AssertionError("Too few packages in PLATFORM_CLASS_PATH ;-)"); - if (nestedClasses < 3000) - throw new AssertionError("Too few nested classes in PLATFORM_CLASS_PATH ;-)"); } /* * If -XX:+AggressiveOpts has been used to test, the option currently diff --git a/langtools/test/tools/javac/processing/model/type/BoundsTest.java b/langtools/test/tools/javac/processing/model/type/BoundsTest.java index 59c73ef6a0c..c67f4882a71 100644 --- a/langtools/test/tools/javac/processing/model/type/BoundsTest.java +++ b/langtools/test/tools/javac/processing/model/type/BoundsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -25,6 +25,7 @@ * @test * @bug 6499673 * @library /tools/javac/lib + * @ignore 8062245 Test executes incorrect class * @build JavacTestingAbstractProcessor BoundsTest * @run main BoundsTest * @summary Assertion check for TypeVariable.getUpperBound() fails @@ -113,15 +114,19 @@ public class BoundsTest { } public void run() throws IOException { - runOne(Intersection_name, Intersection_contents, - Intersection_bounds, Intersection_supers); - runOne(Single_name, Single_contents, - Single_bounds, Single_supers); - runOne(NoBounds_name, NoBounds_contents, - NoBounds_bounds, NoBounds_supers); + try { + runOne(Intersection_name, Intersection_contents, + Intersection_bounds, Intersection_supers); + runOne(Single_name, Single_contents, + Single_bounds, Single_supers); + runOne(NoBounds_name, NoBounds_contents, + NoBounds_bounds, NoBounds_supers); - if (0 != errors) - throw new RuntimeException(errors + " errors occurred"); + if (0 != errors) + throw new RuntimeException(errors + " errors occurred"); + } finally { + fm.close(); + } } public static void main(String... args) throws IOException { diff --git a/langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java b/langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java index d474a70762a..f51977a3be6 100644 --- a/langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java +++ b/langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -76,10 +76,14 @@ public class IntersectionPropertiesTest { } public void run() throws IOException { - runOne(Intersection_name, Intersection_contents); + try { + runOne(Intersection_name, Intersection_contents); - if (0 != errors) - throw new RuntimeException(errors + " errors occurred"); + if (0 != errors) + throw new RuntimeException(errors + " errors occurred"); + } finally { + fm.close(); + } } public static void main(String... args) throws IOException { diff --git a/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java index 9270e157bec..d8d398861f1 100644 --- a/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java @@ -104,11 +104,12 @@ public class TestDocComments extends JavacTestingAbstractProcessor { } }; JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); - Iterable units = fm.getJavaFileObjects(files); - JavacTask t = (JavacTask) c.getTask(null, fm, dl, Arrays.asList(opts), null, units); - t.parse(); - t.analyze(); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + Iterable units = fm.getJavaFileObjects(files); + JavacTask t = (JavacTask) c.getTask(null, fm, dl, Arrays.asList(opts), null, units); + t.parse(); + t.analyze(); + } } static void test_javac_cmd(String[] opts, File[] files) { diff --git a/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestPackageInfoComments.java b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestPackageInfoComments.java index 296f7d7bf7c..0114cccbebe 100644 --- a/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestPackageInfoComments.java +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestPackageInfoComments.java @@ -60,11 +60,12 @@ public class TestPackageInfoComments extends JavacTestingAbstractProcessor { } }; JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); - Iterable units = fm.getJavaFileObjects(files); - JavacTask t = (JavacTask) c.getTask(null, fm, dl, Arrays.asList(opts), null, units); - t.parse(); - t.analyze(); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + Iterable units = fm.getJavaFileObjects(files); + JavacTask t = (JavacTask) c.getTask(null, fm, dl, Arrays.asList(opts), null, units); + t.parse(); + t.analyze(); + } } // -- Annotation processor: Check all PackageDecl's have a doc comment diff --git a/langtools/test/tools/javac/processing/options/testCommandLineClasses/Test.java b/langtools/test/tools/javac/processing/options/testCommandLineClasses/Test.java index b610a14e644..a3313af9559 100644 --- a/langtools/test/tools/javac/processing/options/testCommandLineClasses/Test.java +++ b/langtools/test/tools/javac/processing/options/testCommandLineClasses/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -67,16 +67,17 @@ public class Test extends JavacTestingAbstractProcessor { void test(List names) throws Exception { System.err.println("test: " + names); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); - File testClasses = new File(System.getProperty("test.classes")); - fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(testClasses)); - JavaCompiler.CompilationTask task = compiler.getTask( - null, null, null, Arrays.asList("-proc:only"), names, null); - task.setProcessors(Arrays.asList(new Test())); - boolean ok = task.call(); - if (!ok) - error("compilation failed"); - System.err.println(); + try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { + File testClasses = new File(System.getProperty("test.classes")); + fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(testClasses)); + JavaCompiler.CompilationTask task = compiler.getTask( + null, null, null, Arrays.asList("-proc:only"), names, null); + task.setProcessors(Arrays.asList(new Test())); + boolean ok = task.call(); + if (!ok) + error("compilation failed"); + System.err.println(); + } } List reverse(List list) { diff --git a/langtools/test/tools/javac/processing/rounds/BaseClassesNotReRead.java b/langtools/test/tools/javac/processing/rounds/BaseClassesNotReRead.java index ebdc9c809e3..74e98539f07 100644 --- a/langtools/test/tools/javac/processing/rounds/BaseClassesNotReRead.java +++ b/langtools/test/tools/javac/processing/rounds/BaseClassesNotReRead.java @@ -49,19 +49,20 @@ public class BaseClassesNotReRead extends AbstractProcessor { void run() throws IOException { File sources = new File(System.getProperty("test.src")); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); - Iterable files = - fm.getJavaFileObjects(new File(sources, "BaseClassesNotReReadSource.java")); - DiagnosticListener noErrors = new DiagnosticListener() { - @Override - public void report(Diagnostic diagnostic) { - throw new IllegalStateException(diagnostic.toString()); - } - }; - JavaFileManager manager = new OnlyOneReadFileManager(fm); - Iterable options = Arrays.asList("-processor", "BaseClassesNotReRead"); - JavacTask task = (JavacTask) compiler.getTask(null, manager, noErrors, options, null, files); - task.analyze(); + try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { + Iterable files = + fm.getJavaFileObjects(new File(sources, "BaseClassesNotReReadSource.java")); + DiagnosticListener noErrors = new DiagnosticListener() { + @Override + public void report(Diagnostic diagnostic) { + throw new IllegalStateException(diagnostic.toString()); + } + }; + JavaFileManager manager = new OnlyOneReadFileManager(fm); + Iterable options = Arrays.asList("-processor", "BaseClassesNotReRead"); + JavacTask task = (JavacTask) compiler.getTask(null, manager, noErrors, options, null, files); + task.analyze(); + } } int round = 1; diff --git a/langtools/test/tools/javac/profiles/ProfileOptionTest.java b/langtools/test/tools/javac/profiles/ProfileOptionTest.java index abd89cbf5ca..ab3cdc18128 100644 --- a/langtools/test/tools/javac/profiles/ProfileOptionTest.java +++ b/langtools/test/tools/javac/profiles/ProfileOptionTest.java @@ -236,24 +236,28 @@ public class ProfileOptionTest { /** Run all test cases. */ void run() throws Exception { - initTestClasses(); + try { + initTestClasses(); - for (Method m: getClass().getDeclaredMethods()) { - Annotation a = m.getAnnotation(Test.class); - if (a != null) { - System.err.println(m.getName()); - try { - m.invoke(this, new Object[] { }); - } catch (InvocationTargetException e) { - Throwable cause = e.getCause(); - throw (cause instanceof Exception) ? ((Exception) cause) : e; + for (Method m: getClass().getDeclaredMethods()) { + Annotation a = m.getAnnotation(Test.class); + if (a != null) { + System.err.println(m.getName()); + try { + m.invoke(this, new Object[] { }); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + throw (cause instanceof Exception) ? ((Exception) cause) : e; + } + System.err.println(); } - System.err.println(); } - } - if (errors > 0) - throw new Exception(errors + " errors occurred"); + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } finally { + fm.close(); + } } void error(String msg) { diff --git a/langtools/test/tools/javac/resolve/ResolveHarness.java b/langtools/test/tools/javac/resolve/ResolveHarness.java index 1abd5c45960..ebde19eb317 100644 --- a/langtools/test/tools/javac/resolve/ResolveHarness.java +++ b/langtools/test/tools/javac/resolve/ResolveHarness.java @@ -71,13 +71,17 @@ public class ResolveHarness implements javax.tools.DiagnosticListener 0) { - throw new AssertionError("Errors were found"); + try { + fm.setLocation(SOURCE_PATH, + Arrays.asList(new File(System.getProperty("test.src"), "tests"))); + for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(JavaFileObject.Kind.SOURCE), true)) { + new ResolveHarness(jfo).check(); + } + if (nerrors > 0) { + throw new AssertionError("Errors were found"); + } + } finally { + fm.close(); } } diff --git a/langtools/test/tools/javac/tree/ClassTreeTest.java b/langtools/test/tools/javac/tree/ClassTreeTest.java index f1cec3b438b..d00af9c316c 100644 --- a/langtools/test/tools/javac/tree/ClassTreeTest.java +++ b/langtools/test/tools/javac/tree/ClassTreeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -41,25 +41,26 @@ public class ClassTreeTest { void run() throws Exception { JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - List opts = Collections.emptyList(); - File testSrc = new File(System.getProperty("test.src")); - File thisFile = new File(testSrc, ClassTreeTest.class.getSimpleName() + ".java"); - Iterable fos = fm.getJavaFileObjects(thisFile); - JavacTask task = tool.getTask(null, fm, null, opts, null, fos); - for (CompilationUnitTree cu: task.parse()) { - check(cu, "CLASS", Tree.Kind.CLASS); - check(cu, "INTERFACE", Tree.Kind.INTERFACE); - check(cu, "ENUM", Tree.Kind.ENUM); - check(cu, "ANNOTATION_TYPE", Tree.Kind.ANNOTATION_TYPE); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + List opts = Collections.emptyList(); + File testSrc = new File(System.getProperty("test.src")); + File thisFile = new File(testSrc, ClassTreeTest.class.getSimpleName() + ".java"); + Iterable fos = fm.getJavaFileObjects(thisFile); + JavacTask task = tool.getTask(null, fm, null, opts, null, fos); + for (CompilationUnitTree cu: task.parse()) { + check(cu, "CLASS", Tree.Kind.CLASS); + check(cu, "INTERFACE", Tree.Kind.INTERFACE); + check(cu, "ENUM", Tree.Kind.ENUM); + check(cu, "ANNOTATION_TYPE", Tree.Kind.ANNOTATION_TYPE); + } + + int expected = 4; + if (checks != expected) + error("Unexpected number of checks performed; expected: " + expected + ", found: " + checks); + + if (errors > 0) + throw new Exception(errors + " errors found"); } - - int expected = 4; - if (checks != expected) - error("Unexpected number of checks performed; expected: " + expected + ", found: " + checks); - - if (errors > 0) - throw new Exception(errors + " errors found"); } void check(CompilationUnitTree cu, String name, Tree.Kind k) { diff --git a/langtools/test/tools/javac/tree/DocCommentToplevelTest.java b/langtools/test/tools/javac/tree/DocCommentToplevelTest.java index 7ab036ff98a..4060973c496 100644 --- a/langtools/test/tools/javac/tree/DocCommentToplevelTest.java +++ b/langtools/test/tools/javac/tree/DocCommentToplevelTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -90,24 +90,25 @@ public class DocCommentToplevelTest { public static void main(String... args) throws Exception { //create default shared JavaCompiler - reused across multiple compilations JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { - for (PackageKind pk : PackageKind.values()) { - for (ImportKind ik : ImportKind.values()) { - for (ModifierKind mk1 : ModifierKind.values()) { - for (ModifierKind mk2 : ModifierKind.values()) { - for (ToplevelDocKind tdk : ToplevelDocKind.values()) { - new DocCommentToplevelTest(pk, ik, mk1, mk2, tdk).run(comp, fm); + for (PackageKind pk : PackageKind.values()) { + for (ImportKind ik : ImportKind.values()) { + for (ModifierKind mk1 : ModifierKind.values()) { + for (ModifierKind mk2 : ModifierKind.values()) { + for (ToplevelDocKind tdk : ToplevelDocKind.values()) { + new DocCommentToplevelTest(pk, ik, mk1, mk2, tdk).run(comp, fm); + } } } } } + + if (errors > 0) + throw new AssertionError(errors + " errors found"); + + System.out.println(checks + " checks were made"); } - - if (errors > 0) - throw new AssertionError(errors + " errors found"); - - System.out.println(checks + " checks were made"); } PackageKind pk; diff --git a/langtools/test/tools/javac/tree/MissingSemicolonTest.java b/langtools/test/tools/javac/tree/MissingSemicolonTest.java index c6b257ed8e1..4d6787bc4f9 100644 --- a/langtools/test/tools/javac/tree/MissingSemicolonTest.java +++ b/langtools/test/tools/javac/tree/MissingSemicolonTest.java @@ -47,7 +47,7 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.util.Context; public class MissingSemicolonTest { - public static void main(String... args) { + public static void main(String... args) throws IOException { String testSrc = System.getProperty("test.src"); File baseDir = new File(testSrc); boolean ok = new MissingSemicolonTest().run(baseDir, args); @@ -56,24 +56,28 @@ public class MissingSemicolonTest { } } - boolean run(File baseDir, String... args) { - if (args.length == 0) { - throw new IllegalStateException("Needs input files."); + boolean run(File baseDir, String... args) throws IOException { + try { + if (args.length == 0) { + throw new IllegalStateException("Needs input files."); + } + + for (String arg : args) { + File file = new File(baseDir, arg); + if (file.exists()) + test(file); + else + error("File not found: " + file); + } + + System.err.println(fileCount + " files read"); + if (errors > 0) + System.err.println(errors + " errors"); + + return errors == 0; + } finally { + fm.close(); } - - for (String arg : args) { - File file = new File(baseDir, arg); - if (file.exists()) - test(file); - else - error("File not found: " + file); - } - - System.err.println(fileCount + " files read"); - if (errors > 0) - System.err.println(errors + " errors"); - - return errors == 0; } void test(File file) { diff --git a/langtools/test/tools/javac/tree/PrettySimpleStringTest.java b/langtools/test/tools/javac/tree/PrettySimpleStringTest.java index 26788308361..47ffaf95752 100644 --- a/langtools/test/tools/javac/tree/PrettySimpleStringTest.java +++ b/langtools/test/tools/javac/tree/PrettySimpleStringTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -46,27 +46,28 @@ public class PrettySimpleStringTest { File testSrc = new File(System.getProperty("test.src")); File thisFile = new File(testSrc, getClass().getName() + ".java"); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - JavacTask task = tool.getTask(null, fm, null, null, null, - fm.getJavaFileObjects(thisFile)); - Iterable trees = task.parse(); - CompilationUnitTree thisTree = trees.iterator().next(); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + JavacTask task = tool.getTask(null, fm, null, null, null, + fm.getJavaFileObjects(thisFile)); + Iterable trees = task.parse(); + CompilationUnitTree thisTree = trees.iterator().next(); - { // test default - String thisSrc = Pretty.toSimpleString((JCTree) thisTree); - System.err.println(thisSrc); - String expect = "import jav[...]} } }"; - if (!thisSrc.equals(expect)) { - throw new Exception("unexpected result"); + { // test default + String thisSrc = Pretty.toSimpleString((JCTree) thisTree); + System.err.println(thisSrc); + String expect = "import jav[...]} } }"; + if (!thisSrc.equals(expect)) { + throw new Exception("unexpected result"); + } } - } - { // test explicit length - String thisSrc = Pretty.toSimpleString((JCTree) thisTree, 32); - System.err.println(thisSrc); - String expect = "import java.io.Fil[...]; } } } }"; - if (!thisSrc.equals(expect)) { - throw new Exception("unexpected result"); + { // test explicit length + String thisSrc = Pretty.toSimpleString((JCTree) thisTree, 32); + System.err.println(thisSrc); + String expect = "import java.io.Fil[...]} } } } }"; + if (!thisSrc.equals(expect)) { + throw new Exception("unexpected result"); + } } } } diff --git a/langtools/test/tools/javac/tree/T6963934.java b/langtools/test/tools/javac/tree/T6963934.java index a64e16dce91..98484ae54c2 100644 --- a/langtools/test/tools/javac/tree/T6963934.java +++ b/langtools/test/tools/javac/tree/T6963934.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -42,17 +42,18 @@ public class T6963934 { File testSrc = new File(System.getProperty("test.src")); File thisSrc = new File(testSrc, T6963934.class.getSimpleName() + ".java"); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); - JavacTask task = (JavacTask) compiler.getTask(null, fileManager, null, null, null, - fileManager.getJavaFileObjects(thisSrc)); - CompilationUnitTree tree = task.parse().iterator().next(); - int count = 0; - for (ImportTree importTree : tree.getImports()) { - System.out.println(importTree); - count++; + try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) { + JavacTask task = (JavacTask) compiler.getTask(null, fileManager, null, null, null, + fileManager.getJavaFileObjects(thisSrc)); + CompilationUnitTree tree = task.parse().iterator().next(); + int count = 0; + for (ImportTree importTree : tree.getImports()) { + System.out.println(importTree); + count++; + } + int expected = 7; + if (count != expected) + throw new Exception("unexpected number of imports found: " + count + ", expected: " + expected); } - int expected = 7; - if (count != expected) - throw new Exception("unexpected number of imports found: " + count + ", expected: " + expected); } } diff --git a/langtools/test/tools/javac/tree/T6993305.java b/langtools/test/tools/javac/tree/T6993305.java index 24a2a6c1fb1..a470b185bd2 100644 --- a/langtools/test/tools/javac/tree/T6993305.java +++ b/langtools/test/tools/javac/tree/T6993305.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -59,18 +59,19 @@ public class T6993305 { File testSrc = new File(System.getProperty("test.src")); JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { - File f = new File(testSrc, T6993305.class.getSimpleName() + ".java"); - Iterable fos = fm.getJavaFileObjects(f); - JavacTask task = tool.getTask(null, fm, null, null, null, fos); - Iterable cus = task.parse(); + File f = new File(testSrc, T6993305.class.getSimpleName() + ".java"); + Iterable fos = fm.getJavaFileObjects(f); + JavacTask task = tool.getTask(null, fm, null, null, null, fos); + Iterable cus = task.parse(); - TestScanner s = new TestScanner(); - s.scan(cus, task); + TestScanner s = new TestScanner(); + s.scan(cus, task); - if (errors > 0) - throw new Exception(errors + " errors occurred"); + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } } void error(String msg) { diff --git a/langtools/test/tools/javac/tree/TestToString.java b/langtools/test/tools/javac/tree/TestToString.java index d5644bcb6e2..9f3f6548abd 100644 --- a/langtools/test/tools/javac/tree/TestToString.java +++ b/langtools/test/tools/javac/tree/TestToString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -63,12 +63,16 @@ public class TestToString { } void run() throws Exception { - for (String s: statements) { - test(s); - } + try { + for (String s: statements) { + test(s); + } - if (errors > 0) - throw new Exception(errors + " errors found"); + if (errors > 0) + throw new Exception(errors + " errors found"); + } finally { + fm.close(); + } } void test(String stmt) throws IOException { diff --git a/langtools/test/tools/javac/tree/TreePosRoundsTest.java b/langtools/test/tools/javac/tree/TreePosRoundsTest.java index 29a41b60795..39304a2ce9c 100644 --- a/langtools/test/tools/javac/tree/TreePosRoundsTest.java +++ b/langtools/test/tools/javac/tree/TreePosRoundsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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,18 +54,19 @@ public class TreePosRoundsTest extends AbstractProcessor { String testSrc = System.getProperty("test.src"); String testClasses = System.getProperty("test.classes"); JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); - String thisName = TreePosRoundsTest.class.getName(); - File thisFile = new File(testSrc, thisName + ".java"); - Iterable files = fm.getJavaFileObjects(thisFile); - List options = Arrays.asList( - "-proc:only", - "-processor", thisName, - "-processorpath", testClasses); - CompilationTask t = c.getTask(null, fm, null, options, null, files); - boolean ok = t.call(); - if (!ok) - throw new Exception("processing failed"); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + String thisName = TreePosRoundsTest.class.getName(); + File thisFile = new File(testSrc, thisName + ".java"); + Iterable files = fm.getJavaFileObjects(thisFile); + List options = Arrays.asList( + "-proc:only", + "-processor", thisName, + "-processorpath", testClasses); + CompilationTask t = c.getTask(null, fm, null, options, null, files); + boolean ok = t.call(); + if (!ok) + throw new Exception("processing failed"); + } } Filer filer; @@ -155,6 +156,9 @@ public class TreePosRoundsTest extends AbstractProcessor { //System.err.println(" encl: " +enclKind); if (enclKind == Tree.Kind.CLASS || enclKind == Tree.Kind.BLOCK) expect += ";"; + // t-w-r- adds implicit final: remove it + if (enclKind == Tree.Kind.TRY && expect.startsWith("final ")) + expect = expect.substring(6); } //System.err.println("expect: " + expect); diff --git a/langtools/test/tools/javac/tree/TreePosTest.java b/langtools/test/tools/javac/tree/TreePosTest.java index f1723211b9c..c82ee41d4a5 100644 --- a/langtools/test/tools/javac/tree/TreePosTest.java +++ b/langtools/test/tools/javac/tree/TreePosTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -113,7 +113,7 @@ public class TreePosTest { * args is the value of ${test.src}. In jtreg mode, the -r option can be * given to change the default base directory to the root test directory. */ - public static void main(String... args) { + public static void main(String... args) throws IOException { String testSrc = System.getProperty("test.src"); File baseDir = (testSrc == null) ? null : new File(testSrc); boolean ok = new TreePosTest().run(baseDir, args); @@ -133,61 +133,65 @@ public class TreePosTest { * @param args command line args * @return true if successful or in gui mode */ - boolean run(File baseDir, String... args) { - if (args.length == 0) { - usage(System.out); - return true; - } + boolean run(File baseDir, String... args) throws IOException { + try { + if (args.length == 0) { + usage(System.out); + return true; + } - List files = new ArrayList(); - for (int i = 0; i < args.length; i++) { - String arg = args[i]; - if (arg.equals("-encoding") && i + 1 < args.length) - encoding = args[++i]; - else if (arg.equals("-gui")) - gui = true; - else if (arg.equals("-q")) - quiet = true; - else if (arg.equals("-v")) - verbose = true; - else if (arg.equals("-t") && i + 1 < args.length) - tags.add(args[++i]); - else if (arg.equals("-ef") && i + 1 < args.length) - excludeFiles.add(new File(baseDir, args[++i])); - else if (arg.equals("-et") && i + 1 < args.length) - excludeTags.add(args[++i]); - else if (arg.equals("-r")) { - if (excludeFiles.size() > 0) - throw new Error("-r must be used before -ef"); - File d = baseDir; - while (!new File(d, "TEST.ROOT").exists()) { - d = d.getParentFile(); - if (d == null) - throw new Error("cannot find TEST.ROOT"); + List files = new ArrayList(); + for (int i = 0; i < args.length; i++) { + String arg = args[i]; + if (arg.equals("-encoding") && i + 1 < args.length) + encoding = args[++i]; + else if (arg.equals("-gui")) + gui = true; + else if (arg.equals("-q")) + quiet = true; + else if (arg.equals("-v")) + verbose = true; + else if (arg.equals("-t") && i + 1 < args.length) + tags.add(args[++i]); + else if (arg.equals("-ef") && i + 1 < args.length) + excludeFiles.add(new File(baseDir, args[++i])); + else if (arg.equals("-et") && i + 1 < args.length) + excludeTags.add(args[++i]); + else if (arg.equals("-r")) { + if (excludeFiles.size() > 0) + throw new Error("-r must be used before -ef"); + File d = baseDir; + while (!new File(d, "TEST.ROOT").exists()) { + d = d.getParentFile(); + if (d == null) + throw new Error("cannot find TEST.ROOT"); + } + baseDir = d; + } + else if (arg.startsWith("-")) + throw new Error("unknown option: " + arg); + else { + while (i < args.length) + files.add(new File(baseDir, args[i++])); } - baseDir = d; } - else if (arg.startsWith("-")) - throw new Error("unknown option: " + arg); - else { - while (i < args.length) - files.add(new File(baseDir, args[i++])); + + for (File file: files) { + if (file.exists()) + test(file); + else + error("File not found: " + file); } + + if (fileCount != 1) + System.err.println(fileCount + " files read"); + if (errors > 0) + System.err.println(errors + " errors"); + + return (gui || errors == 0); + } finally { + fm.close(); } - - for (File file: files) { - if (file.exists()) - test(file); - else - error("File not found: " + file); - } - - if (fileCount != 1) - System.err.println(fileCount + " files read"); - if (errors > 0) - System.err.println(errors + " errors"); - - return (gui || errors == 0); } /** diff --git a/langtools/test/tools/javac/unit/T6198196.java b/langtools/test/tools/javac/unit/T6198196.java index f90a35971fa..3948ae789a7 100644 --- a/langtools/test/tools/javac/unit/T6198196.java +++ b/langtools/test/tools/javac/unit/T6198196.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ -28,6 +28,7 @@ * @author Peter von der Ah\u00e9 */ +import java.io.IOException; import java.util.Arrays; import javax.tools.*; @@ -42,21 +43,25 @@ public class T6198196 { + filename + ") != " + result); System.out.format("OK: endsWith(%s, %s) = %s%n", pathname, filename, result); } - public static void main(String[] args) { + public static void main(String[] args) throws IOException { fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null); - boolean windows = System.getProperty("os.name").startsWith("Windows"); - test("/x/y/z/package-info.java", pkginf, true); - if (windows) { - test("\\x\\y\\z\\package-info.java", pkginf, true); - test("..\\x\\y\\z\\package-info.java", pkginf, true); - } else { - test("\\x\\y\\z\\package-info.java", pkginf, false); - test("..\\x\\y\\z\\package-info.java", pkginf, false); + try { + boolean windows = System.getProperty("os.name").startsWith("Windows"); + test("/x/y/z/package-info.java", pkginf, true); + if (windows) { + test("\\x\\y\\z\\package-info.java", pkginf, true); + test("..\\x\\y\\z\\package-info.java", pkginf, true); + } else { + test("\\x\\y\\z\\package-info.java", pkginf, false); + test("..\\x\\y\\z\\package-info.java", pkginf, false); + } + test("Package-info.java", pkginf, false); + test("../x/y/z/package-info.java", pkginf, true); + test("/x/y/z/package-info.java", pkginf, true); + test("x/y/z/package-info.java", pkginf, true); + test("package-info.java", pkginf, true); + } finally { + fm.close(); } - test("Package-info.java", pkginf, false); - test("../x/y/z/package-info.java", pkginf, true); - test("/x/y/z/package-info.java", pkginf, true); - test("x/y/z/package-info.java", pkginf, true); - test("package-info.java", pkginf, true); } } diff --git a/langtools/test/tools/javac/varargs/6199075/T6199075.java b/langtools/test/tools/javac/varargs/6199075/T6199075.java index ba9d3c01851..fa9f1a029c4 100644 --- a/langtools/test/tools/javac/varargs/6199075/T6199075.java +++ b/langtools/test/tools/javac/varargs/6199075/T6199075.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -143,20 +143,24 @@ public class T6199075 { } void test() throws Exception { - for (TypeKind formal1 : TypeKind.values()) { - VarargsMethod m1 = new VarargsMethod(formal1); - for (TypeKind formal2 : TypeKind.values()) { - VarargsMethod m2 = new VarargsMethod(formal2); - for (TypeKind actual : TypeKind.values()) { - for (ArgumentsArity argsArity : ArgumentsArity.values()) { - compileAndCheck(m1, m2, actual, argsArity); + try { + for (TypeKind formal1 : TypeKind.values()) { + VarargsMethod m1 = new VarargsMethod(formal1); + for (TypeKind formal2 : TypeKind.values()) { + VarargsMethod m2 = new VarargsMethod(formal2); + for (TypeKind actual : TypeKind.values()) { + for (ArgumentsArity argsArity : ArgumentsArity.values()) { + compileAndCheck(m1, m2, actual, argsArity); + } } } } - } - System.out.println("Total checks made: " + checkCount); - System.out.println("Bytecode checks made: " + bytecodeCheckCount); + System.out.println("Total checks made: " + checkCount); + System.out.println("Bytecode checks made: " + bytecodeCheckCount); + } finally { + fm.close(); + } } // Create a single file manager and reuse it for each compile to save time. diff --git a/langtools/test/tools/javac/varargs/7043922/T7043922.java b/langtools/test/tools/javac/varargs/7043922/T7043922.java index 496bb28775d..c5e98c0ce5e 100644 --- a/langtools/test/tools/javac/varargs/7043922/T7043922.java +++ b/langtools/test/tools/javac/varargs/7043922/T7043922.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -146,22 +146,26 @@ public class T7043922 { static final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); public static void main(String... args) throws Exception { - for (ClassKind classKind1 : ClassKind.values()) { - for (ConstructorKind constrKind1 : ConstructorKind.values()) { - if (!classKind1.isConstructorOk(constrKind1)) continue; - for (ClassKind classKind2 : ClassKind.values()) { - for (ConstructorKind constrKind2 : ConstructorKind.values()) { - if (!classKind2.isConstructorOk(constrKind2)) continue; - for (ClassKind classKind3 : ClassKind.values()) { - for (ConstructorKind constrKind3 : ConstructorKind.values()) { - if (!classKind3.isConstructorOk(constrKind3)) continue; - new T7043922(new ClassKind[] { classKind1, classKind2, classKind3 }, - new ConstructorKind[] { constrKind1, constrKind2, constrKind3 }).compileAndCheck(); + try { + for (ClassKind classKind1 : ClassKind.values()) { + for (ConstructorKind constrKind1 : ConstructorKind.values()) { + if (!classKind1.isConstructorOk(constrKind1)) continue; + for (ClassKind classKind2 : ClassKind.values()) { + for (ConstructorKind constrKind2 : ConstructorKind.values()) { + if (!classKind2.isConstructorOk(constrKind2)) continue; + for (ClassKind classKind3 : ClassKind.values()) { + for (ConstructorKind constrKind3 : ConstructorKind.values()) { + if (!classKind3.isConstructorOk(constrKind3)) continue; + new T7043922(new ClassKind[] { classKind1, classKind2, classKind3 }, + new ConstructorKind[] { constrKind1, constrKind2, constrKind3 }).compileAndCheck(); + } } } } } } + } finally { + fm.close(); } } diff --git a/langtools/test/tools/javac/versions/Versions.java b/langtools/test/tools/javac/versions/Versions.java index e65eb6777e3..0e8a42e3dc0 100644 --- a/langtools/test/tools/javac/versions/Versions.java +++ b/langtools/test/tools/javac/versions/Versions.java @@ -278,22 +278,25 @@ public class Versions { protected boolean compile(String sourceFile, Listoptions) { JavaCompiler.CompilationTask jctask; - StandardJavaFileManager fm = javacompiler.getStandardFileManager(null, null, null); - Iterable files = fm.getJavaFileObjects(sourceFile); + try (StandardJavaFileManager fm = javacompiler.getStandardFileManager(null, null, null)) { + Iterable files = fm.getJavaFileObjects(sourceFile); - jctask = javacompiler.getTask( - null, // Writer - fm, // JavaFileManager - null, // DiagnosticListener - options, // Iterable - null, // Iterable classes - files); // Iterable + jctask = javacompiler.getTask( + null, // Writer + fm, // JavaFileManager + null, // DiagnosticListener + options, // Iterable + null, // Iterable classes + files); // Iterable - try { - return jctask.call(); - } catch (IllegalStateException e) { - System.err.println(e); - return false; + try { + return jctask.call(); + } catch (IllegalStateException e) { + System.err.println(e); + return false; + } + } catch (IOException e) { + throw new Error(e); } } diff --git a/langtools/test/tools/javadoc/CheckResourceKeys.java b/langtools/test/tools/javadoc/CheckResourceKeys.java index b3de88f7050..0a68f22cba5 100644 --- a/langtools/test/tools/javadoc/CheckResourceKeys.java +++ b/langtools/test/tools/javadoc/CheckResourceKeys.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, 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 @@ -140,41 +140,42 @@ public class CheckResourceKeys { Set getCodeKeys() throws IOException { Set results = new TreeSet(); JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - JavaFileManager fm = c.getStandardFileManager(null, null, null); - JavaFileManager.Location javadocLoc = findJavadocLocation(fm); - String[] pkgs = { - "com.sun.tools.doclets", - "com.sun.tools.javadoc" - }; - for (String pkg: pkgs) { - for (JavaFileObject fo: fm.list(javadocLoc, - pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) { - String name = fo.getName(); - // ignore resource files - if (name.matches(".*resources.[A-Za-z_0-9]+\\.class.*")) - continue; - scan(fo, results); + try (JavaFileManager fm = c.getStandardFileManager(null, null, null)) { + JavaFileManager.Location javadocLoc = findJavadocLocation(fm); + String[] pkgs = { + "com.sun.tools.doclets", + "com.sun.tools.javadoc" + }; + for (String pkg: pkgs) { + for (JavaFileObject fo: fm.list(javadocLoc, + pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) { + String name = fo.getName(); + // ignore resource files + if (name.matches(".*resources.[A-Za-z_0-9]+\\.class.*")) + continue; + scan(fo, results); + } } + + // special handling for code strings synthesized in + // com.sun.tools.doclets.internal.toolkit.util.Util.getTypeName + String[] extras = { + "AnnotationType", "Class", "Enum", "Error", "Exception", "Interface" + }; + for (String s: extras) { + if (results.contains("doclet." + s)) + results.add("doclet." + s.toLowerCase()); + } + + // special handling for code strings synthesized in + // com.sun.tools.javadoc.Messager + results.add("javadoc.error.msg"); + results.add("javadoc.note.msg"); + results.add("javadoc.note.pos.msg"); + results.add("javadoc.warning.msg"); + + return results; } - - // special handling for code strings synthesized in - // com.sun.tools.doclets.internal.toolkit.util.Util.getTypeName - String[] extras = { - "AnnotationType", "Class", "Enum", "Error", "Exception", "Interface" - }; - for (String s: extras) { - if (results.contains("doclet." + s)) - results.add("doclet." + s.toLowerCase()); - } - - // special handling for code strings synthesized in - // com.sun.tools.javadoc.Messager - results.add("javadoc.error.msg"); - results.add("javadoc.note.msg"); - results.add("javadoc.note.pos.msg"); - results.add("javadoc.warning.msg"); - - return results; } // depending on how the test is run, javadoc may be on bootclasspath or classpath diff --git a/langtools/test/tools/javadoc/api/basic/DocletPathTest.java b/langtools/test/tools/javadoc/api/basic/DocletPathTest.java index daf40cc4037..5d1c9943936 100644 --- a/langtools/test/tools/javadoc/api/basic/DocletPathTest.java +++ b/langtools/test/tools/javadoc/api/basic/DocletPathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -59,34 +59,36 @@ public class DocletPathTest extends APITest { createSimpleJavaFileObject("DocletOnDocletPath", docletSrcText); File docletDir = getOutDir("classes"); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager cfm = compiler.getStandardFileManager(null, null, null); - cfm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(docletDir)); - Iterable cfiles = Arrays.asList(docletSrc); - if (!compiler.getTask(null, cfm, null, null, null, cfiles).call()) - throw new Exception("cannot compile doclet"); + try (StandardJavaFileManager cfm = compiler.getStandardFileManager(null, null, null)) { + cfm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(docletDir)); + Iterable cfiles = Arrays.asList(docletSrc); + if (!compiler.getTask(null, cfm, null, null, null, cfiles).call()) + throw new Exception("cannot compile doclet"); + } JavaFileObject srcFile = createSimpleJavaFileObject(); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir("api"); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - fm.setLocation(DocumentationTool.Location.DOCLET_PATH, Arrays.asList(docletDir)); - Iterable files = Arrays.asList(srcFile); - Iterable options = Arrays.asList("-doclet", "DocletOnDocletPath"); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - DocumentationTask t = tool.getTask(pw, fm, null, null, options, files); - boolean ok = t.call(); - String out = sw.toString(); - System.err.println(">>" + out + "<<"); - if (ok) { - if (out.contains(TEST_STRING)) { - System.err.println("doclet executed as expected"); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir("api"); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + fm.setLocation(DocumentationTool.Location.DOCLET_PATH, Arrays.asList(docletDir)); + Iterable files = Arrays.asList(srcFile); + Iterable options = Arrays.asList("-doclet", "DocletOnDocletPath"); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + DocumentationTask t = tool.getTask(pw, fm, null, null, options, files); + boolean ok = t.call(); + String out = sw.toString(); + System.err.println(">>" + out + "<<"); + if (ok) { + if (out.contains(TEST_STRING)) { + System.err.println("doclet executed as expected"); + } else { + error("test string not found in doclet output"); + } } else { - error("test string not found in doclet output"); + error("task failed"); } - } else { - error("task failed"); } } diff --git a/langtools/test/tools/javadoc/api/basic/GetTask_DiagListenerTest.java b/langtools/test/tools/javadoc/api/basic/GetTask_DiagListenerTest.java index fafc02835a9..05062db2460 100644 --- a/langtools/test/tools/javadoc/api/basic/GetTask_DiagListenerTest.java +++ b/langtools/test/tools/javadoc/api/basic/GetTask_DiagListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -60,27 +60,28 @@ public class GetTask_DiagListenerTest extends APITest { public void testDiagListener() throws Exception { JavaFileObject srcFile = createSimpleJavaFileObject("pkg/C", "package pkg; public error { }"); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable files = Arrays.asList(srcFile); - DiagnosticCollector dc = new DiagnosticCollector(); - DocumentationTask t = tool.getTask(null, fm, dc, null, null, files); - if (t.call()) { - throw new Exception("task succeeded unexpectedly"); - } else { - List diagCodes = new ArrayList(); - for (Diagnostic d: dc.getDiagnostics()) { - System.err.println(d); - diagCodes.add(d.getCode()); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DiagnosticCollector dc = new DiagnosticCollector(); + DocumentationTask t = tool.getTask(null, fm, dc, null, null, files); + if (t.call()) { + throw new Exception("task succeeded unexpectedly"); + } else { + List diagCodes = new ArrayList(); + for (Diagnostic d: dc.getDiagnostics()) { + System.err.println(d); + diagCodes.add(d.getCode()); + } + List expect = Arrays.asList( + "javadoc.note.msg", // Loading source file + "compiler.err.expected3", // class, interface, or enum expected + "javadoc.note.msg"); // 1 error + if (!diagCodes.equals(expect)) + throw new Exception("unexpected diagnostics occurred"); + System.err.println("diagnostics received as expected"); } - List expect = Arrays.asList( - "javadoc.note.msg", // Loading source file - "compiler.err.expected3", // class, interface, or enum expected - "javadoc.note.msg"); // 1 error - if (!diagCodes.equals(expect)) - throw new Exception("unexpected diagnostics occurred"); - System.err.println("diagnostics received as expected"); } } diff --git a/langtools/test/tools/javadoc/api/basic/GetTask_DocletClassTest.java b/langtools/test/tools/javadoc/api/basic/GetTask_DocletClassTest.java index c5085043cff..e0383e62f99 100644 --- a/langtools/test/tools/javadoc/api/basic/GetTask_DocletClassTest.java +++ b/langtools/test/tools/javadoc/api/basic/GetTask_DocletClassTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -70,20 +70,21 @@ public class GetTask_DocletClassTest extends APITest { "pkg/C", "package pkg; /** " + key + "*/ public class C { }"); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable files = Arrays.asList(srcFile); - DocumentationTask t = tool.getTask(null, fm, null, TestDoclet.class, null, files); - if (t.call()) { - System.err.println("task succeeded"); - if (TestDoclet.lastCaller.equals(String.valueOf(key))) - System.err.println("found expected key: " + key); - else - error("Expected key not found"); - checkFiles(outDir, Collections.emptySet()); - } else { - throw new Exception("task failed"); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, TestDoclet.class, null, files); + if (t.call()) { + System.err.println("task succeeded"); + if (TestDoclet.lastCaller.equals(String.valueOf(key))) + System.err.println("found expected key: " + key); + else + error("Expected key not found"); + checkFiles(outDir, Collections.emptySet()); + } else { + throw new Exception("task failed"); + } } } @@ -115,20 +116,21 @@ public class GetTask_DocletClassTest extends APITest { public void testBadDoclet() throws Exception { JavaFileObject srcFile = createSimpleJavaFileObject(); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable files = Arrays.asList(srcFile); - DocumentationTask t = tool.getTask(null, fm, null, BadDoclet.class, null, files); - try { - t.call(); - error("call completed without exception"); - } catch (RuntimeException e) { - Throwable c = e.getCause(); - if (c.getClass() == UnexpectedError.class) - System.err.println("exception caught as expected: " + c); - else - throw e; + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, BadDoclet.class, null, files); + try { + t.call(); + error("call completed without exception"); + } catch (RuntimeException e) { + Throwable c = e.getCause(); + if (c.getClass() == UnexpectedError.class) + System.err.println("exception caught as expected: " + c); + else + throw e; + } } } diff --git a/langtools/test/tools/javadoc/api/basic/GetTask_FileObjectsTest.java b/langtools/test/tools/javadoc/api/basic/GetTask_FileObjectsTest.java index fc3cd1419b5..22e6ac913c5 100644 --- a/langtools/test/tools/javadoc/api/basic/GetTask_FileObjectsTest.java +++ b/langtools/test/tools/javadoc/api/basic/GetTask_FileObjectsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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,16 +54,17 @@ public class GetTask_FileObjectsTest extends APITest { File testSrc = new File(System.getProperty("test.src")); File srcFile = new File(testSrc, "pkg/C.java"); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable files = fm.getJavaFileObjects(srcFile); - DocumentationTask t = tool.getTask(null, fm, null, null, null, files); - if (t.call()) { - System.err.println("task succeeded"); - checkFiles(outDir, standardExpectFiles); - } else { - throw new Exception("task failed"); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = fm.getJavaFileObjects(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + if (t.call()) { + System.err.println("task succeeded"); + checkFiles(outDir, standardExpectFiles); + } else { + throw new Exception("task failed"); + } } } @@ -75,16 +76,17 @@ public class GetTask_FileObjectsTest extends APITest { public void testMemoryFileObject() throws Exception { JavaFileObject srcFile = createSimpleJavaFileObject(); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable files = Arrays.asList(srcFile); - DocumentationTask t = tool.getTask(null, fm, null, null, null, files); - if (t.call()) { - System.err.println("task succeeded"); - checkFiles(outDir, standardExpectFiles); - } else { - throw new Exception("task failed"); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + if (t.call()) { + System.err.println("task succeeded"); + checkFiles(outDir, standardExpectFiles); + } else { + throw new Exception("task failed"); + } } } @@ -96,15 +98,16 @@ public class GetTask_FileObjectsTest extends APITest { File testSrc = new File(System.getProperty("test.src")); File srcFile = new File(testSrc, "pkg/C.class"); // unacceptable file kind DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable files = fm.getJavaFileObjects(srcFile); - try { - DocumentationTask t = tool.getTask(null, fm, null, null, null, files); - error("getTask succeeded, no exception thrown"); - } catch (IllegalArgumentException e) { - System.err.println("exception caught as expected: " + e); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = fm.getJavaFileObjects(srcFile); + try { + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + error("getTask succeeded, no exception thrown"); + } catch (IllegalArgumentException e) { + System.err.println("exception caught as expected: " + e); + } } } @@ -114,15 +117,16 @@ public class GetTask_FileObjectsTest extends APITest { @Test public void testNull() throws Exception { DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable files = Arrays.asList((JavaFileObject) null); - try { - DocumentationTask t = tool.getTask(null, fm, null, null, null, files); - error("getTask succeeded, no exception thrown"); - } catch (NullPointerException e) { - System.err.println("exception caught as expected: " + e); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList((JavaFileObject) null); + try { + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + error("getTask succeeded, no exception thrown"); + } catch (NullPointerException e) { + System.err.println("exception caught as expected: " + e); + } } } diff --git a/langtools/test/tools/javadoc/api/basic/GetTask_OptionsTest.java b/langtools/test/tools/javadoc/api/basic/GetTask_OptionsTest.java index c6da9c8927d..1f39eb331f5 100644 --- a/langtools/test/tools/javadoc/api/basic/GetTask_OptionsTest.java +++ b/langtools/test/tools/javadoc/api/basic/GetTask_OptionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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,19 +54,20 @@ public class GetTask_OptionsTest extends APITest { public void testNoIndex() throws Exception { JavaFileObject srcFile = createSimpleJavaFileObject(); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable files = Arrays.asList(srcFile); - Iterable options = Arrays.asList("-noindex"); - DocumentationTask t = tool.getTask(null, fm, null, null, options, files); - if (t.call()) { - System.err.println("task succeeded"); - Set expectFiles = new TreeSet(standardExpectFiles); - expectFiles.remove("index-all.html"); - checkFiles(outDir, expectFiles); - } else { - error("task failed"); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + Iterable options = Arrays.asList("-noindex"); + DocumentationTask t = tool.getTask(null, fm, null, null, options, files); + if (t.call()) { + System.err.println("task succeeded"); + Set expectFiles = new TreeSet(standardExpectFiles); + expectFiles.remove("index-all.html"); + checkFiles(outDir, expectFiles); + } else { + error("task failed"); + } } } @@ -77,16 +78,17 @@ public class GetTask_OptionsTest extends APITest { public void testNull() throws Exception { JavaFileObject srcFile = createSimpleJavaFileObject(); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable options = Arrays.asList((String) null); - Iterable files = Arrays.asList(srcFile); - try { - DocumentationTask t = tool.getTask(null, fm, null, null, options, files); - error("getTask succeeded, no exception thrown"); - } catch (NullPointerException e) { - System.err.println("exception caught as expected: " + e); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable options = Arrays.asList((String) null); + Iterable files = Arrays.asList(srcFile); + try { + DocumentationTask t = tool.getTask(null, fm, null, null, options, files); + error("getTask succeeded, no exception thrown"); + } catch (NullPointerException e) { + System.err.println("exception caught as expected: " + e); + } } } diff --git a/langtools/test/tools/javadoc/api/basic/GetTask_WriterTest.java b/langtools/test/tools/javadoc/api/basic/GetTask_WriterTest.java index 389b8d60be1..083db35073d 100644 --- a/langtools/test/tools/javadoc/api/basic/GetTask_WriterTest.java +++ b/langtools/test/tools/javadoc/api/basic/GetTask_WriterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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,25 +54,26 @@ public class GetTask_WriterTest extends APITest { public void testWriter() throws Exception { JavaFileObject srcFile = createSimpleJavaFileObject(); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable files = Arrays.asList(srcFile); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - DocumentationTask t = tool.getTask(pw, fm, null, null, null, files); - if (t.call()) { - System.err.println("task succeeded"); - checkFiles(outDir, standardExpectFiles); - String out = sw.toString(); - System.err.println(">>" + out + "<<"); - for (String f: standardExpectFiles) { - String f1 = f.replace('/', File.separatorChar); - if (f1.endsWith(".html") && !out.contains(f1)) - throw new Exception("expected string not found: " + f1); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + DocumentationTask t = tool.getTask(pw, fm, null, null, null, files); + if (t.call()) { + System.err.println("task succeeded"); + checkFiles(outDir, standardExpectFiles); + String out = sw.toString(); + System.err.println(">>" + out + "<<"); + for (String f: standardExpectFiles) { + String f1 = f.replace('/', File.separatorChar); + if (f1.endsWith(".html") && !out.contains(f1)) + throw new Exception("expected string not found: " + f1); + } + } else { + throw new Exception("task failed"); } - } else { - throw new Exception("task failed"); } } } diff --git a/langtools/test/tools/javadoc/api/basic/JavadocTaskImplTest.java b/langtools/test/tools/javadoc/api/basic/JavadocTaskImplTest.java index 9a372cdea80..8e9b7831fc4 100644 --- a/langtools/test/tools/javadoc/api/basic/JavadocTaskImplTest.java +++ b/langtools/test/tools/javadoc/api/basic/JavadocTaskImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -56,18 +56,19 @@ public class JavadocTaskImplTest extends APITest { public void testRawCall() throws Exception { JavaFileObject srcFile = createSimpleJavaFileObject(); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable files = Arrays.asList(srcFile); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); - @SuppressWarnings("rawtypes") - Callable t = tool.getTask(null, fm, null, null, null, files); + @SuppressWarnings("rawtypes") + Callable t = tool.getTask(null, fm, null, null, null, files); - if (t.call() == Boolean.TRUE) { - System.err.println("task succeeded"); - } else { - throw new Exception("task failed"); + if (t.call() == Boolean.TRUE) { + System.err.println("task succeeded"); + } else { + throw new Exception("task failed"); + } } } @@ -77,14 +78,15 @@ public class JavadocTaskImplTest extends APITest { Iterable files = Arrays.asList(srcFile); Context c = new Context(); Messager.preRegister(c, "javadoc"); - StandardJavaFileManager fm = new JavacFileManager(c, true, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - DocumentationTask t = new JavadocTaskImpl(c, null, null, files); - if (t.call()) { - System.err.println("task succeeded"); - } else { - throw new Exception("task failed"); + try (StandardJavaFileManager fm = new JavacFileManager(c, true, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + DocumentationTask t = new JavadocTaskImpl(c, null, null, files); + if (t.call()) { + System.err.println("task succeeded"); + } else { + throw new Exception("task failed"); + } } } @@ -94,14 +96,15 @@ public class JavadocTaskImplTest extends APITest { Iterable files = Arrays.asList(srcFile); Context c = new Context(); Messager.preRegister(c, "javadoc"); - StandardJavaFileManager fm = new JavacFileManager(c, true, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - try { - DocumentationTask t = new JavadocTaskImpl(c, null, null, files);; - error("getTask succeeded, no exception thrown"); - } catch (NullPointerException e) { - System.err.println("exception caught as expected: " + e); + try (StandardJavaFileManager fm = new JavacFileManager(c, true, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + try { + DocumentationTask t = new JavadocTaskImpl(c, null, null, files);; + error("getTask succeeded, no exception thrown"); + } catch (NullPointerException e) { + System.err.println("exception caught as expected: " + e); + } } } } diff --git a/langtools/test/tools/javadoc/api/basic/TagletPathTest.java b/langtools/test/tools/javadoc/api/basic/TagletPathTest.java index 52dd5c81b7e..80b5922e4bb 100644 --- a/langtools/test/tools/javadoc/api/basic/TagletPathTest.java +++ b/langtools/test/tools/javadoc/api/basic/TagletPathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -62,38 +62,40 @@ public class TagletPathTest extends APITest { File tagletSrcFile = new File(testSrc, "taglets/UnderlineTaglet.java"); File tagletDir = getOutDir("classes"); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager cfm = compiler.getStandardFileManager(null, null, null); - cfm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(tagletDir)); - Iterable cfiles = cfm.getJavaFileObjects(tagletSrcFile); - if (!compiler.getTask(null, cfm, null, null, null, cfiles).call()) - throw new Exception("cannot compile taglet"); + try (StandardJavaFileManager cfm = compiler.getStandardFileManager(null, null, null)) { + cfm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(tagletDir)); + Iterable cfiles = cfm.getJavaFileObjects(tagletSrcFile); + if (!compiler.getTask(null, cfm, null, null, null, cfiles).call()) + throw new Exception("cannot compile taglet"); + } JavaFileObject srcFile = createSimpleJavaFileObject("pkg/C", testSrcText); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir("api"); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - fm.setLocation(DocumentationTool.Location.TAGLET_PATH, Arrays.asList(tagletDir)); - Iterable files = Arrays.asList(srcFile); - Iterable options = Arrays.asList("-taglet", "UnderlineTaglet"); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - DocumentationTask t = tool.getTask(pw, fm, null, null, options, files); - boolean ok = t.call(); - String out = sw.toString(); - System.err.println(">>" + out + "<<"); - if (ok) { - File f = new File(outDir, "pkg/C.html"); - List doc = Files.readAllLines(f.toPath(), Charset.defaultCharset()); - for (String line: doc) { - if (line.contains("" + TEST_STRING + "")) { - System.err.println("taglet executed as expected"); - return; + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir("api"); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + fm.setLocation(DocumentationTool.Location.TAGLET_PATH, Arrays.asList(tagletDir)); + Iterable files = Arrays.asList(srcFile); + Iterable options = Arrays.asList("-taglet", "UnderlineTaglet"); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + DocumentationTask t = tool.getTask(pw, fm, null, null, options, files); + boolean ok = t.call(); + String out = sw.toString(); + System.err.println(">>" + out + "<<"); + if (ok) { + File f = new File(outDir, "pkg/C.html"); + List doc = Files.readAllLines(f.toPath(), Charset.defaultCharset()); + for (String line: doc) { + if (line.contains("" + TEST_STRING + "")) { + System.err.println("taglet executed as expected"); + return; + } } + error("expected text not found in output " + f); + } else { + error("task failed"); } - error("expected text not found in output " + f); - } else { - error("task failed"); } } diff --git a/langtools/test/tools/javadoc/api/basic/Task_reuseTest.java b/langtools/test/tools/javadoc/api/basic/Task_reuseTest.java index 5bda0d34d74..1fb3c7502df 100644 --- a/langtools/test/tools/javadoc/api/basic/Task_reuseTest.java +++ b/langtools/test/tools/javadoc/api/basic/Task_reuseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -77,16 +77,17 @@ public class Task_reuseTest extends APITest { private DocumentationTask getAndRunTask() throws Exception { JavaFileObject srcFile = createSimpleJavaFileObject(); DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - File outDir = getOutDir(); - fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); - Iterable files = Arrays.asList(srcFile); - DocumentationTask t = tool.getTask(null, fm, null, null, null, files); - if (t.call()) { - System.err.println("task succeeded"); - return t; - } else { - throw new Exception("task failed"); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + if (t.call()) { + System.err.println("task succeeded"); + return t; + } else { + throw new Exception("task failed"); + } } } } diff --git a/langtools/test/tools/javadoc/doclint/DocLintTest.java b/langtools/test/tools/javadoc/doclint/DocLintTest.java index 346b457f29f..f291c072f35 100644 --- a/langtools/test/tools/javadoc/doclint/DocLintTest.java +++ b/langtools/test/tools/javadoc/doclint/DocLintTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, 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 @@ -121,60 +121,64 @@ public class DocLintTest { void run() throws Exception { javadoc = ToolProvider.getSystemDocumentationTool(); fm = javadoc.getStandardFileManager(null, null, null); - fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); - file = new SimpleJavaFileObject(URI.create("Test.java"), JavaFileObject.Kind.SOURCE) { - @Override - public CharSequence getCharContent(boolean ignoreEncoding) { - return code; - } - }; + try { + fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); + file = new SimpleJavaFileObject(URI.create("Test.java"), JavaFileObject.Kind.SOURCE) { + @Override + public CharSequence getCharContent(boolean ignoreEncoding) { + return code; + } + }; - test(Collections.emptyList(), - Main.Result.ERROR, - EnumSet.of(Message.DL_ERR9A, Message.DL_WRN12A)); + test(Collections.emptyList(), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR9A, Message.DL_WRN12A)); - test(Arrays.asList(rawDiags), - Main.Result.ERROR, - EnumSet.of(Message.DL_ERR9, Message.DL_WRN12)); + test(Arrays.asList(rawDiags), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR9, Message.DL_WRN12)); - test(Arrays.asList("-Xdoclint:none"), - Main.Result.OK, - EnumSet.of(Message.JD_WRN10, Message.JD_WRN13)); + test(Arrays.asList("-Xdoclint:none"), + Main.Result.OK, + EnumSet.of(Message.JD_WRN10, Message.JD_WRN13)); - test(Arrays.asList(rawDiags, "-Xdoclint"), - Main.Result.ERROR, - EnumSet.of(Message.DL_ERR9, Message.DL_WRN12)); + test(Arrays.asList(rawDiags, "-Xdoclint"), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR9, Message.DL_WRN12)); - test(Arrays.asList(rawDiags, "-Xdoclint:all/public"), - Main.Result.ERROR, - EnumSet.of(Message.OPT_BADQUAL)); + test(Arrays.asList(rawDiags, "-Xdoclint:all/public"), + Main.Result.ERROR, + EnumSet.of(Message.OPT_BADQUAL)); - test(Arrays.asList(rawDiags, "-Xdoclint:all", "-public"), - Main.Result.OK, - EnumSet.of(Message.DL_WRN12)); + test(Arrays.asList(rawDiags, "-Xdoclint:all", "-public"), + Main.Result.OK, + EnumSet.of(Message.DL_WRN12)); - test(Arrays.asList(rawDiags, "-Xdoclint:syntax"), - Main.Result.OK, - EnumSet.of(Message.DL_WRN12)); + test(Arrays.asList(rawDiags, "-Xdoclint:syntax"), + Main.Result.OK, + EnumSet.of(Message.DL_WRN12)); - test(Arrays.asList(rawDiags, "-private"), - Main.Result.ERROR, - EnumSet.of(Message.DL_ERR6, Message.DL_ERR9, Message.DL_WRN12)); + test(Arrays.asList(rawDiags, "-private"), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR6, Message.DL_ERR9, Message.DL_WRN12)); - test(Arrays.asList(rawDiags, "-Xdoclint:syntax", "-private"), - Main.Result.ERROR, - EnumSet.of(Message.DL_ERR6, Message.DL_WRN12)); + test(Arrays.asList(rawDiags, "-Xdoclint:syntax", "-private"), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR6, Message.DL_WRN12)); - test(Arrays.asList(rawDiags, "-Xdoclint:reference"), - Main.Result.ERROR, - EnumSet.of(Message.DL_ERR9)); + test(Arrays.asList(rawDiags, "-Xdoclint:reference"), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR9)); - test(Arrays.asList(rawDiags, "-Xdoclint:badarg"), - Main.Result.ERROR, - EnumSet.of(Message.OPT_BADARG)); + test(Arrays.asList(rawDiags, "-Xdoclint:badarg"), + Main.Result.ERROR, + EnumSet.of(Message.OPT_BADARG)); - if (errors > 0) - throw new Exception(errors + " errors occurred"); + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } finally { + fm.close(); + } } void test(List opts, Main.Result expectResult, Set expectMessages) { diff --git a/langtools/test/tools/javap/TestSuperclass.java b/langtools/test/tools/javap/TestSuperclass.java index 07d3c05ab7c..6923daf2677 100644 --- a/langtools/test/tools/javap/TestSuperclass.java +++ b/langtools/test/tools/javap/TestSuperclass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -77,19 +77,20 @@ public class TestSuperclass { public static void main(String... args) throws Exception { JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); - int errors = 0; + try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) { + int errors = 0; - for (ClassKind ck: ClassKind.values()) { - for (GenericKind gk: GenericKind.values()) { - for (SuperKind sk: SuperKind.values()) { - errors += new TestSuperclass(ck, gk, sk).run(comp, fm); + for (ClassKind ck: ClassKind.values()) { + for (GenericKind gk: GenericKind.values()) { + for (SuperKind sk: SuperKind.values()) { + errors += new TestSuperclass(ck, gk, sk).run(comp, fm); + } } } - } - if (errors > 0) - throw new Exception(errors + " errors found"); + if (errors > 0) + throw new Exception(errors + " errors found"); + } } final ClassKind ck; diff --git a/langtools/test/tools/sjavac/DependencyCollection.java b/langtools/test/tools/sjavac/DependencyCollection.java index b3b6de9ae33..3d610229ebf 100644 --- a/langtools/test/tools/sjavac/DependencyCollection.java +++ b/langtools/test/tools/sjavac/DependencyCollection.java @@ -59,59 +59,60 @@ public class DependencyCollection { Path src = Paths.get(ToolBox.testSrc, "test-input", "src"); JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); - StandardJavaFileManager fileManager = javac.getStandardFileManager(null, null, null); - SmartFileManager smartFileManager = new SmartFileManager(fileManager); - smartFileManager.setSymbolFileEnabled(false); - Iterable fileObjects = - fileManager.getJavaFileObjectsFromFiles(Arrays.asList(src.resolve("pkg/Test.java").toFile())); - JavacTaskImpl task = (JavacTaskImpl) javac.getTask(new PrintWriter(System.out), - smartFileManager, - null, - Arrays.asList("-d", "classes", - "-sourcepath", src.toAbsolutePath().toString()), - null, - fileObjects); - DependencyCollector depsCollector = new DependencyCollector(); - task.addTaskListener(depsCollector); - task.doCall(); + try (StandardJavaFileManager fileManager = javac.getStandardFileManager(null, null, null)) { + SmartFileManager smartFileManager = new SmartFileManager(fileManager); + smartFileManager.setSymbolFileEnabled(false); + Iterable fileObjects = + fileManager.getJavaFileObjectsFromFiles(Arrays.asList(src.resolve("pkg/Test.java").toFile())); + JavacTaskImpl task = (JavacTaskImpl) javac.getTask(new PrintWriter(System.out), + smartFileManager, + null, + Arrays.asList("-d", "classes", + "-sourcepath", src.toAbsolutePath().toString()), + null, + fileObjects); + DependencyCollector depsCollector = new DependencyCollector(); + task.addTaskListener(depsCollector); + task.doCall(); - // Find pkg symbol - PackageSymbol pkg = findPkgSymbolWithName(depsCollector.getSourcePackages(), "pkg"); - Set foundDependencies = depsCollector.getDependenciesForPkg(pkg); + // Find pkg symbol + PackageSymbol pkg = findPkgSymbolWithName(depsCollector.getSourcePackages(), "pkg"); + Set foundDependencies = depsCollector.getDependenciesForPkg(pkg); - // Print dependencies - System.out.println("Found dependencies:"); - foundDependencies.stream() - .sorted(Comparator.comparing(DependencyCollection::extractNumber)) - .forEach(p -> System.out.println(" " + p)); + // Print dependencies + System.out.println("Found dependencies:"); + foundDependencies.stream() + .sorted(Comparator.comparing(DependencyCollection::extractNumber)) + .forEach(p -> System.out.println(" " + p)); - // Check result - Set found = foundDependencies.stream() - .map(DependencyCollection::extractNumber) - .collect(Collectors.toSet()); - found.remove(-1); // Dependencies with no number (java.lang etc) - Set expected = new HashSet<>(); - for (int i = 2; i <= 30; i++) { - if (i == 15) continue; // Case 15 correspond to the type of a throw-away return value. - expected.add(i); + // Check result + Set found = foundDependencies.stream() + .map(DependencyCollection::extractNumber) + .collect(Collectors.toSet()); + found.remove(-1); // Dependencies with no number (java.lang etc) + Set expected = new HashSet<>(); + for (int i = 2; i <= 30; i++) { + if (i == 15) continue; // Case 15 correspond to the type of a throw-away return value. + expected.add(i); + } + + Set missing = new HashSet<>(expected); + missing.removeAll(found); + if (missing.size() > 0) { + System.out.println("Missing dependencies:"); + missing.forEach(i -> System.out.println(" Dependency " + i)); + } + + Set unexpected = new HashSet<>(found); + unexpected.removeAll(expected); + if (unexpected.size() > 0) { + System.out.println("Unexpected dependencies found:"); + unexpected.forEach(i -> System.out.println(" Dependency " + i)); + } + + if (missing.size() > 0 || unexpected.size() > 0) + throw new AssertionError("Missing and/or unexpected dependencies found."); } - - Set missing = new HashSet<>(expected); - missing.removeAll(found); - if (missing.size() > 0) { - System.out.println("Missing dependencies:"); - missing.forEach(i -> System.out.println(" Dependency " + i)); - } - - Set unexpected = new HashSet<>(found); - unexpected.removeAll(expected); - if (unexpected.size() > 0) { - System.out.println("Unexpected dependencies found:"); - unexpected.forEach(i -> System.out.println(" Dependency " + i)); - } - - if (missing.size() > 0 || unexpected.size() > 0) - throw new AssertionError("Missing and/or unexpected dependencies found."); } private static PackageSymbol findPkgSymbolWithName(Set syms, String name) { From 4ce27b2f9ececd863062cb6fe65c86e464215287 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 29 Oct 2014 18:01:22 -0700 Subject: [PATCH 50/67] 8062504: javadoc Start does not close file managers that it opens Reviewed-by: ksrini --- .../share/classes/com/sun/tools/javadoc/Start.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Start.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Start.java index de8f96cef65..3d4db8623f3 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Start.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Start.java @@ -88,6 +88,9 @@ public class Start extends ToolOption.Helper { */ private boolean apiMode; + private JavaFileManager fileManager; + private boolean closeFileManagerOnExit; + Start(String programName, PrintWriter errWriter, PrintWriter warnWriter, @@ -239,6 +242,12 @@ public class Start extends ToolOption.Helper { messager.error(Messager.NOPOS, "main.fatal.exception"); failed = true; } finally { + if (fileManager != null && closeFileManagerOnExit) { + try { + fileManager.close(); + } catch (IOException ignore) { + } + } messager.exitNotice(); messager.flush(); } @@ -270,7 +279,8 @@ public class Start extends ToolOption.Helper { } - JavaFileManager fileManager = context.get(JavaFileManager.class); + fileManager = context.get(JavaFileManager.class); + setDocletInvoker(docletClass, fileManager, argv); compOpts = Options.instance(context); @@ -333,6 +343,7 @@ public class Start extends ToolOption.Helper { if (fileManager == null) { JavacFileManager.preRegister(context); fileManager = context.get(JavaFileManager.class); + closeFileManagerOnExit = true; } if (fileManager instanceof BaseFileManager) { ((BaseFileManager) fileManager).handleOptions(fileManagerOpts); From 342df9829af1d45ca0344b899baf3ed9629add19 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 29 Oct 2014 19:07:34 -0700 Subject: [PATCH 51/67] 8062514: Update ToolTester tests to close file manager Reviewed-by: darcy --- .../com/sun/tools/javac/file/JavacFileManager.java | 4 ++++ langtools/test/tools/javac/api/6406133/T6406133.java | 6 ++++-- langtools/test/tools/javac/api/6410643/T6410643.java | 8 ++++++-- langtools/test/tools/javac/api/6411310/T6411310.java | 6 ++++-- langtools/test/tools/javac/api/6411333/T6411333.java | 9 ++++++--- langtools/test/tools/javac/api/6412656/T6412656.java | 9 ++++++--- langtools/test/tools/javac/api/6415780/T6415780.java | 10 ++++++---- langtools/test/tools/javac/api/6418694/T6418694.java | 9 ++++++--- langtools/test/tools/javac/api/6421111/T6421111.java | 9 ++++++--- langtools/test/tools/javac/api/6421756/T6421756.java | 9 ++++++--- langtools/test/tools/javac/api/6422215/T6422215.java | 8 +++++--- langtools/test/tools/javac/api/6422327/T6422327.java | 9 ++++++--- langtools/test/tools/javac/api/6423003/T6423003.java | 9 ++++++--- langtools/test/tools/javac/api/6431257/T6431257.java | 6 ++++-- langtools/test/tools/javac/api/6437349/T6437349.java | 6 ++++-- langtools/test/tools/javac/api/6437999/T6437999.java | 6 ++++-- langtools/test/tools/javac/api/6440333/T6440333.java | 6 ++++-- langtools/test/tools/javac/api/6440528/T6440528.java | 6 ++++-- langtools/test/tools/javac/api/6468404/T6468404.java | 8 +++++--- langtools/test/tools/javac/api/6731573/T6731573.java | 6 ++++-- langtools/test/tools/javac/api/6733837/T6733837.java | 9 ++++++--- .../test/tools/javac/api/TestJavacTaskScanner.java | 4 +++- langtools/test/tools/javac/api/TestResolveError.java | 4 +++- langtools/test/tools/javac/api/guide/Test.java | 6 ++++-- langtools/test/tools/javac/api/lib/ToolTester.java | 9 +++++++-- 25 files changed, 123 insertions(+), 58 deletions(-) diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java index 72c6574410e..82f34dec311 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -130,6 +130,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil if (register) context.put(JavaFileManager.class, this); setContext(context); + if (System.getProperty("show.fm.open.close") != null) + System.err.println("JavacFileManager.open " + this.hashCode()); } /** @@ -571,6 +573,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil */ @DefinedBy(Api.COMPILER) public void close() { + if (System.getProperty("show.fm.open.close") != null) + System.err.println("JavacFileManager.close " + this.hashCode()); for (Iterator i = archives.values().iterator(); i.hasNext(); ) { Archive a = i.next(); i.remove(); diff --git a/langtools/test/tools/javac/api/6406133/T6406133.java b/langtools/test/tools/javac/api/6406133/T6406133.java index 26eb3e06785..d3a3b428af3 100644 --- a/langtools/test/tools/javac/api/6406133/T6406133.java +++ b/langtools/test/tools/javac/api/6406133/T6406133.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2014, 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 @@ -106,6 +106,8 @@ public class T6406133 extends ToolTester { } public static void main(String... args) throws Exception { - new T6406133().test(); + try (T6406133 t = new T6406133()) { + t.test(); + } } } diff --git a/langtools/test/tools/javac/api/6410643/T6410643.java b/langtools/test/tools/javac/api/6410643/T6410643.java index 075fffaad82..448f4bd29be 100644 --- a/langtools/test/tools/javac/api/6410643/T6410643.java +++ b/langtools/test/tools/javac/api/6410643/T6410643.java @@ -31,6 +31,7 @@ * @run main T6410643 */ +import java.io.IOException; import javax.tools.JavaFileObject; import static java.util.Collections.singleton; @@ -68,7 +69,10 @@ public class T6410643 extends ToolTester { testGetTask(s, s, f); System.err.println("Test result: PASSED"); } - public static void main(String... args) { - new T6410643().test(args); + + public static void main(String... args) throws IOException { + try (T6410643 t = new T6410643()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6411310/T6411310.java b/langtools/test/tools/javac/api/6411310/T6411310.java index 885f34751f3..2d9580f0376 100644 --- a/langtools/test/tools/javac/api/6411310/T6411310.java +++ b/langtools/test/tools/javac/api/6411310/T6411310.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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,6 +54,8 @@ public class T6411310 extends ToolTester { } public static void main(String... args) throws IOException { - new T6411310().test(args); + try (T6411310 t = new T6411310()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6411333/T6411333.java b/langtools/test/tools/javac/api/6411333/T6411333.java index 146f135ffa8..abe3c17fe7a 100644 --- a/langtools/test/tools/javac/api/6411333/T6411333.java +++ b/langtools/test/tools/javac/api/6411333/T6411333.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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,7 +82,10 @@ public class T6411333 extends ToolTester { testRelativeUri("util/List.java", false); testRelativeUri("/util/List.java", true); } - public static void main(String... args) { - new T6411333().test(args); + + public static void main(String... args) throws IOException { + try (T6411333 t = new T6411333()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6412656/T6412656.java b/langtools/test/tools/javac/api/6412656/T6412656.java index 2dc64b79a47..a3911928436 100644 --- a/langtools/test/tools/javac/api/6412656/T6412656.java +++ b/langtools/test/tools/javac/api/6412656/T6412656.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -31,6 +31,7 @@ * @run main T6412656 */ +import java.io.IOException; import java.util.Set; import java.util.Collections; import javax.lang.model.element.TypeElement; @@ -52,8 +53,10 @@ public class T6412656 extends ToolTester { System.out.println("OK"); } - public static void main(String... args) { - new T6412656().test(args); + public static void main(String... args) throws IOException { + try (T6412656 t = new T6412656()) { + t.test(args); + } } @SupportedAnnotationTypes("*") diff --git a/langtools/test/tools/javac/api/6415780/T6415780.java b/langtools/test/tools/javac/api/6415780/T6415780.java index caf8c06ac35..5b155ce3e30 100644 --- a/langtools/test/tools/javac/api/6415780/T6415780.java +++ b/langtools/test/tools/javac/api/6415780/T6415780.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ * @run main T6415780 */ +import java.io.IOException; import static javax.tools.StandardLocation.CLASS_PATH; public class T6415780 extends ToolTester { @@ -39,8 +40,9 @@ public class T6415780 extends ToolTester { System.out.println(fm.getClassLoader(CLASS_PATH).toString()); // null-check } - public static void main(String... args) { - T6415780 tester = new T6415780(); - tester.test(); + public static void main(String... args) throws IOException { + try (T6415780 tester = new T6415780()) { + tester.test(); + } } } diff --git a/langtools/test/tools/javac/api/6418694/T6418694.java b/langtools/test/tools/javac/api/6418694/T6418694.java index f23cbf8dbfb..b54429f99a1 100644 --- a/langtools/test/tools/javac/api/6418694/T6418694.java +++ b/langtools/test/tools/javac/api/6418694/T6418694.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ * @run main T6418694 */ +import java.io.IOException; import javax.tools.StandardLocation; public class T6418694 extends ToolTester { @@ -52,7 +53,9 @@ public class T6418694 extends ToolTester { } } } - public static void main(String... args) { - new T6418694().test(args); + public static void main(String... args) throws IOException { + try (T6418694 t = new T6418694()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6421111/T6421111.java b/langtools/test/tools/javac/api/6421111/T6421111.java index 96fbf2c8c0a..04b477af49e 100644 --- a/langtools/test/tools/javac/api/6421111/T6421111.java +++ b/langtools/test/tools/javac/api/6421111/T6421111.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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,6 +33,7 @@ */ import java.io.File; +import java.io.IOException; import java.net.URI; import java.util.Arrays; import java.util.Collections; @@ -101,8 +102,10 @@ public class T6421111 extends ToolTester { return SourceVersion.latest(); } } - public static void main(String... args) { - new T6421111().test(args); + public static void main(String... args) throws IOException { + try (T6421111 t = new T6421111()) { + t.test(args); + } } public static AssertionError error(String format, Object... args) { return new AssertionError(String.format(format, args)); diff --git a/langtools/test/tools/javac/api/6421756/T6421756.java b/langtools/test/tools/javac/api/6421756/T6421756.java index 9d20e030c6b..06736f09181 100644 --- a/langtools/test/tools/javac/api/6421756/T6421756.java +++ b/langtools/test/tools/javac/api/6421756/T6421756.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ * @run main T6421756 */ +import java.io.IOException; import java.util.Collections; public class T6421756 extends ToolTester { @@ -44,7 +45,9 @@ public class T6421756 extends ToolTester { System.out.println("OK: got expected error " + e.getLocalizedMessage()); } } - public static void main(String... args) { - new T6421756().test(args); + public static void main(String... args) throws IOException { + try (T6421756 t = new T6421756()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6422215/T6422215.java b/langtools/test/tools/javac/api/6422215/T6422215.java index c9a9c392e4b..fb8154000b3 100644 --- a/langtools/test/tools/javac/api/6422215/T6422215.java +++ b/langtools/test/tools/javac/api/6422215/T6422215.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -46,7 +46,9 @@ public class T6422215 extends ToolTester { System.out.println("OK: caught expected exception: " + e.getLocalizedMessage()); } } - public static void main(String... args) { - new T6422215().test(args); + public static void main(String... args) throws IOException { + try (T6422215 t = new T6422215()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6422327/T6422327.java b/langtools/test/tools/javac/api/6422327/T6422327.java index e5f9f220eaf..e61be9220c5 100644 --- a/langtools/test/tools/javac/api/6422327/T6422327.java +++ b/langtools/test/tools/javac/api/6422327/T6422327.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ */ import java.io.File; +import java.io.IOException; public class T6422327 extends ToolTester { void test(String... args) { @@ -43,7 +44,9 @@ public class T6422327 extends ToolTester { System.err.println("OK, got expected exception: " + e.getLocalizedMessage()); } } - public static void main(String... args) { - new T6422327().test(args); + public static void main(String... args) throws IOException { + try (T6422327 t = new T6422327()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6423003/T6423003.java b/langtools/test/tools/javac/api/6423003/T6423003.java index e7fe2f3fda3..6dcb02fa2d4 100644 --- a/langtools/test/tools/javac/api/6423003/T6423003.java +++ b/langtools/test/tools/javac/api/6423003/T6423003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ * @run main T6423003 */ +import java.io.IOException; import java.util.Arrays; public class T6423003 extends ToolTester { @@ -44,7 +45,9 @@ public class T6423003 extends ToolTester { } throw new AssertionError("Expected IllegalStateException not thrown"); } - public static void main(String... args) { - new T6423003().test(args); + public static void main(String... args) throws IOException { + try (T6423003 t = new T6423003()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6431257/T6431257.java b/langtools/test/tools/javac/api/6431257/T6431257.java index 9c0b2a41a65..8f4b33c6328 100644 --- a/langtools/test/tools/javac/api/6431257/T6431257.java +++ b/langtools/test/tools/javac/api/6431257/T6431257.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -67,6 +67,8 @@ public class T6431257 extends ToolTester { } public static void main(String... args) throws IOException { - new T6431257().test(args); + try (T6431257 t = new T6431257()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6437349/T6437349.java b/langtools/test/tools/javac/api/6437349/T6437349.java index af81251dbee..f57d60583dc 100644 --- a/langtools/test/tools/javac/api/6437349/T6437349.java +++ b/langtools/test/tools/javac/api/6437349/T6437349.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -51,6 +51,8 @@ public class T6437349 extends ToolTester { throw new AssertionError(); } public static void main(String... args) throws IOException { - new T6437349().test(args); + try (T6437349 t = new T6437349()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6437999/T6437999.java b/langtools/test/tools/javac/api/6437999/T6437999.java index 2fbe3211fb9..03ab771ec12 100644 --- a/langtools/test/tools/javac/api/6437999/T6437999.java +++ b/langtools/test/tools/javac/api/6437999/T6437999.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -86,6 +86,8 @@ public class T6437999 extends ToolTester { throw new AssertionError("Error in UTF-8 mode"); } public static void main(String... args) throws IOException { - new T6437999().test(args); + try (T6437999 t = new T6437999()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6440333/T6440333.java b/langtools/test/tools/javac/api/6440333/T6440333.java index 984ef4082aa..aa52926c5e3 100644 --- a/langtools/test/tools/javac/api/6440333/T6440333.java +++ b/langtools/test/tools/javac/api/6440333/T6440333.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -50,6 +50,8 @@ public class T6440333 extends ToolTester { } } public static void main(String... args) throws IOException { - new T6440333().test(args); + try (T6440333 t = new T6440333()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6440528/T6440528.java b/langtools/test/tools/javac/api/6440528/T6440528.java index 0fc919486da..f0220121b35 100644 --- a/langtools/test/tools/javac/api/6440528/T6440528.java +++ b/langtools/test/tools/javac/api/6440528/T6440528.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -66,6 +66,8 @@ public class T6440528 extends ToolTester { } public static void main(String... args) throws Exception { - new T6440528().test(args); + try (T6440528 t = new T6440528()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6468404/T6468404.java b/langtools/test/tools/javac/api/6468404/T6468404.java index dafbb36bb94..4a77de42c32 100644 --- a/langtools/test/tools/javac/api/6468404/T6468404.java +++ b/langtools/test/tools/javac/api/6468404/T6468404.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -88,8 +88,10 @@ public class T6468404 extends ToolTester { if (!task.call()) throw new AssertionError(); } - public static void main(String... args) { - new T6468404().test(args); + public static void main(String... args) throws IOException { + try (T6468404 t = new T6468404()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/6731573/T6731573.java b/langtools/test/tools/javac/api/6731573/T6731573.java index b1bdc711c03..5d59447bf3b 100644 --- a/langtools/test/tools/javac/api/6731573/T6731573.java +++ b/langtools/test/tools/javac/api/6731573/T6731573.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2014, 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 @@ -106,6 +106,8 @@ public class T6731573 extends ToolTester { } public static void main(String... args) throws Exception { - new T6731573().test(); + try (T6731573 t = new T6731573()) { + t.test(); + } } } diff --git a/langtools/test/tools/javac/api/6733837/T6733837.java b/langtools/test/tools/javac/api/6733837/T6733837.java index 4f1fcf4a085..b3776d58e1b 100644 --- a/langtools/test/tools/javac/api/6733837/T6733837.java +++ b/langtools/test/tools/javac/api/6733837/T6733837.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2014, 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 @@ -31,6 +31,7 @@ * @run main T6733837 */ +import java.io.IOException; import java.io.StringWriter; import java.io.PrintWriter; import java.net.URI; @@ -43,8 +44,10 @@ import com.sun.source.util.JavacTask; public class T6733837 extends ToolTester { - public static void main(String... args) { - new T6733837().exec(); + public static void main(String... args) throws IOException { + try (T6733837 t = new T6733837()) { + t.exec(); + } } public void exec() { diff --git a/langtools/test/tools/javac/api/TestJavacTaskScanner.java b/langtools/test/tools/javac/api/TestJavacTaskScanner.java index 97b80ec8d9f..39c0979d4ec 100644 --- a/langtools/test/tools/javac/api/TestJavacTaskScanner.java +++ b/langtools/test/tools/javac/api/TestJavacTaskScanner.java @@ -115,7 +115,9 @@ public class TestJavacTaskScanner extends ToolTester { public static void main(String... args) throws IOException { String srcdir = System.getProperty("test.src"); - new TestJavacTaskScanner(new File(srcdir, args[0])).run(); + try (TestJavacTaskScanner t = new TestJavacTaskScanner(new File(srcdir, args[0]))) { + t.run(); + } } private void testGetAllMembers(TypeElement clazz) { diff --git a/langtools/test/tools/javac/api/TestResolveError.java b/langtools/test/tools/javac/api/TestResolveError.java index 88fc21c668d..08dc04c10aa 100644 --- a/langtools/test/tools/javac/api/TestResolveError.java +++ b/langtools/test/tools/javac/api/TestResolveError.java @@ -51,7 +51,9 @@ import com.sun.tools.javac.api.JavacTaskImpl; */ public class TestResolveError extends ToolTester { public static void main(String... args) throws Exception { - new TestResolveError().run(); + try (TestResolveError t = new TestResolveError()) { + t.run(); + } } void run() throws Exception { diff --git a/langtools/test/tools/javac/api/guide/Test.java b/langtools/test/tools/javac/api/guide/Test.java index a05295f8a2b..a2d1afdc94c 100644 --- a/langtools/test/tools/javac/api/guide/Test.java +++ b/langtools/test/tools/javac/api/guide/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -80,7 +80,9 @@ public class Test extends ToolTester { } public static void main(String... args) throws Exception { - new Test().test(args); + try (Test t = new Test()) { + t.test(args); + } } } diff --git a/langtools/test/tools/javac/api/lib/ToolTester.java b/langtools/test/tools/javac/api/lib/ToolTester.java index ba66da84220..8ba24f1d634 100644 --- a/langtools/test/tools/javac/api/lib/ToolTester.java +++ b/langtools/test/tools/javac/api/lib/ToolTester.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, 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 @@ -31,7 +31,7 @@ import static javax.tools.StandardLocation.CLASS_PATH; import static javax.tools.StandardLocation.SOURCE_PATH; import static javax.tools.StandardLocation.CLASS_OUTPUT; -public class ToolTester { +public class ToolTester implements AutoCloseable { public final File test_src = new File(System.getProperty("test.src", ".")); public final File test_classes = new File(System.getProperty("test.classes", ".")); public final List test_class_path = pathToFiles(System.getProperty("test.class.path"), @@ -77,4 +77,9 @@ public class ToolTester { result.addAll(b); return result; } + + @Override + public void close() throws IOException { + fm.close(); + } } From d2c9b8251378127f450ab183dc9d3c29e6919a10 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Thu, 30 Oct 2014 09:13:27 -0400 Subject: [PATCH 52/67] 8062513: doclint warnings in HijrahChronology Use proper markup for < > Reviewed-by: darcy, alanb --- .../share/classes/java/time/chrono/HijrahChronology.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java index c6c6d4a2e8f..5dfee287fd8 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java @@ -146,7 +146,8 @@ import sun.util.logging.PlatformLogger; * property resource that defines the {@code ID}, the {@code calendar type}, * the start of the calendar, the alignment with the * ISO calendar, and the length of each month for a range of years. - * The variants are loaded by HijrahChronology as a resource from hijrah-config-.properties. + * The variants are loaded by HijrahChronology as a resource from + * hijrah-config-<calendar type>.properties. *

* The Hijrah property resource is a set of properties that describe the calendar. * The syntax is defined by {@code java.util.Properties#load(Reader)}. From 63ddccfab06a5753deae0ef2d4c2691e6980b440 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Thu, 30 Oct 2014 07:24:51 -0700 Subject: [PATCH 53/67] 7156085: ArrayIndexOutOfBoundsException throws in UTF8Reader of SAXParser Improve support for supplementary characters Reviewed-by: joehw --- .../org/apache/xerces/internal/impl/io/UTF8Reader.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/io/UTF8Reader.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/io/UTF8Reader.java index df9620ae04f..46242056cd9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/io/UTF8Reader.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/io/UTF8Reader.java @@ -529,6 +529,16 @@ public class UTF8Reader invalidByte(4, 4, b2); } + // check if output buffer is large enough to hold 2 surrogate chars + if (out + 1 >= ch.length) { + fBuffer[0] = (byte)b0; + fBuffer[1] = (byte)b1; + fBuffer[2] = (byte)b2; + fBuffer[3] = (byte)b3; + fOffset = 4; + return out - offset; + } + // decode bytes into surrogate characters int uuuuu = ((b0 << 2) & 0x001C) | ((b1 >> 4) & 0x0003); if (uuuuu > 0x10) { From ccb65f43ee4aee5bbf1461000c386a2f6d469ee1 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Thu, 30 Oct 2014 07:30:33 -0700 Subject: [PATCH 54/67] 7156085: ArrayIndexOutOfBoundsException throws in UTF8Reader of SAXParser Improve support for supplementary characters Reviewed-by: joehw --- .../parse/jdk7156085/UTF8ReaderBug.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 jdk/test/javax/xml/jaxp/testng/parse/jdk7156085/UTF8ReaderBug.java diff --git a/jdk/test/javax/xml/jaxp/testng/parse/jdk7156085/UTF8ReaderBug.java b/jdk/test/javax/xml/jaxp/testng/parse/jdk7156085/UTF8ReaderBug.java new file mode 100644 index 00000000000..993fc61b879 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/testng/parse/jdk7156085/UTF8ReaderBug.java @@ -0,0 +1,64 @@ +/* + * Copyright 2014 Google, Inc. 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. + */ + +package parse.jdk7156085; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.xml.sax.InputSource; +import org.xml.sax.helpers.DefaultHandler; +import org.testng.annotations.Test; + +/** + * JDK-7156085: ArrayIndexOutOfBoundsException throws in UTF8Reader of SAXParser + * https://bugs.openjdk.java.net/browse/JDK-7156085 + * + * XERCESJ-1257: buffer overflow in UTF8Reader for characters out of BMP + * https://issues.apache.org/jira/browse/XERCESJ-1257 + */ +public class UTF8ReaderBug { + @Test + public void shouldAcceptSupplementaryCharacters() throws Throwable { + StringBuilder b = new StringBuilder(""); + for(int i = 5; i < 8223; i++) { + b.append(' '); + } + // Add surrogate characters which overflow the buffer. This shows the need to place an + // overflow check at -- + // com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(UTF8Reader.java:544) + b.append("\uD835\uDC37"); + b.append(""); + sendToParser(b.toString()); + } + + private static void sendToParser(String b) throws Throwable { + byte[] input = b.getBytes("UTF-8"); + ByteArrayInputStream in = new ByteArrayInputStream(input); + + SAXParserFactory spf = SAXParserFactory.newInstance(); + SAXParser p = spf.newSAXParser(); + p.parse(new InputSource(in), new DefaultHandler()); + } +} From f2f6553039cd0214dee65d0f49a2f1fc07f7aabf Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 30 Oct 2014 08:34:49 -0700 Subject: [PATCH 55/67] Added tag jdk9-b37 for changeset afcbbfccf839 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 69ff256efb2..f1c878c526e 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -279,3 +279,4 @@ e4ba01b726e263953ae129be37c94de6ed145b1d jdk9-b33 087b23f35631e68e950496a36fce8ccca612966a jdk9-b34 c173ba994245380fb11ef077d1e59823386840eb jdk9-b35 201d4e235d597a25a2d3ee1404394789ba386119 jdk9-b36 +723a67b0c442391447b1d8aad8b249d06d1032e8 jdk9-b37 From 1f6e40fd8f32c42dc7e6c840566ba04a3eeff847 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 30 Oct 2014 08:34:51 -0700 Subject: [PATCH 56/67] Added tag jdk9-b37 for changeset 410d1a5e1a5c --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 17c78bd5515..93c6e08f8bf 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -279,3 +279,4 @@ cfdac5887952c2dd73c73a1d8d9aa880d0539bbf jdk9-b33 24a0bad5910f775bb4002d1dacf8b3af87c63cd8 jdk9-b34 9bc2dbd3dfb8c9fa88e00056b8b93a81ee6d306e jdk9-b35 ffd90c81d4ef9d94d880fc852e2fc482ecd9b374 jdk9-b36 +7e9add74ad50841fb39dae75db56374aefa1de4c jdk9-b37 From 6adc3da841157cb0a96a8a83448c2c45018a96aa Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 30 Oct 2014 08:34:54 -0700 Subject: [PATCH 57/67] Added tag jdk9-b37 for changeset 566704615ade --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 231cc0b9955..32e64cf79ba 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -439,3 +439,4 @@ af46576a8d7cb4003028b8ee8bf408cfe227315b jdk9-b32 821164b0131a47ca065697c7d27d8f215e608c8d jdk9-b34 438cb613151c4bd290bb732697517cba1cafcb04 jdk9-b35 464ab653fbb17eb518d8ef60f8df301de7ef00d0 jdk9-b36 +b1c2dd843f247a1db19e1e85eb62ca405f72dc26 jdk9-b37 From b412f2a2f0e58e1ff91ed311988c95199c83e534 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 30 Oct 2014 08:34:59 -0700 Subject: [PATCH 58/67] Added tag jdk9-b37 for changeset c4918033790e --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 9e2830b5ad9..9a2a4b4269b 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -279,3 +279,4 @@ b940ca3d2c7e8a279ca850706b89c2ad3a841e82 jdk9-b32 6b343b9b7a7008f5f699a2d99881163cab7a2986 jdk9-b34 b9370464572fc663a38956047aa612d6e7854c3d jdk9-b35 61b4c9acaa58e482db6601ec5dc4fc3d2d8dbb55 jdk9-b36 +48e4ec70cc1c8651e4a0324d91f193c4edd83af9 jdk9-b37 From 7fafb195a6a55023e878dfb2f029937ab2b964e9 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 30 Oct 2014 08:35:00 -0700 Subject: [PATCH 59/67] Added tag jdk9-b37 for changeset a34b97a133ea --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 5f2d2dfcb97..5e757c7285f 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -282,3 +282,4 @@ e58d3ea638c3824f01547596b2a98aa5f77c4a5c jdk9-b30 28ea43d925f1e5250976097a2977dd3e66e11f0b jdk9-b34 afe0c89e2edbdfb1a7ceff3d9b3ff46c4186202f jdk9-b35 84803c3be7f79d29c7dc40749d7743675f64107a jdk9-b36 +90de6ecbff46386a3f9d6f7ca876e7aa6381f50a jdk9-b37 From a4fc3795b6c84025469a3e25572908c4bc03ada1 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 30 Oct 2014 08:35:01 -0700 Subject: [PATCH 60/67] Added tag jdk9-b37 for changeset 88fe05f2d973 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 19f56dc1e90..69c3a4f7482 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -279,3 +279,4 @@ f0870554049807d3392bd7976ab114f7f2b7bafa jdk9-b27 21568031434d7a9dbb0cc6516cc3183d349c2253 jdk9-b34 e549291a0227031310fa91c574891f892d27f959 jdk9-b35 cdcf2e599e42935c2d1d19a24bb19e808aeb43b5 jdk9-b36 +27c3345d6dce39a22c262f30bb1f0e0b00c3709e jdk9-b37 From e9d3130f3d4517c54ee712c5db7d4cd3b826b5a8 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 30 Oct 2014 08:35:04 -0700 Subject: [PATCH 61/67] Added tag jdk9-b37 for changeset f3f667e5870c --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 0fcac23ca3b..385d4c5850b 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -279,3 +279,4 @@ e891e0c4edc5174a4da6d19dc2d59697b79f1916 jdk9-b33 e18407fcede818b30709913784cb6b904030531d jdk9-b34 b8e7bbdd806465a916e64413c283075ceb0a782c jdk9-b35 c536541235e566701ff772700c15de14b75e2979 jdk9-b36 +478972d90f7bf5002615c5b2fb1ec3e0338fcadd jdk9-b37 From baf8cabd665341394a827f8f53683e5ef5e17a1a Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 30 Oct 2014 08:35:05 -0700 Subject: [PATCH 62/67] Added tag jdk9-b37 for changeset 957656314d82 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 79ce8b4076f..9251f3661af 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -270,3 +270,4 @@ b374d8910e7f8de2b7ecacee9ae4cad88f23feab jdk9-b33 4ece2dad8c37f520f1ccc1cf84870f362c8eb9d6 jdk9-b34 63b8da4c958c3bbadfff082c547983f5daa50c0f jdk9-b35 10fe62bc188476abb025e55f55128cbfecf24584 jdk9-b36 +dd7bbdf81a537106cfa9227d1a9a57849cb26b4d jdk9-b37 From 755b2be9af4109f00bd6ceb6b8b9a6b644ce157a Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 30 Oct 2014 17:49:45 +0100 Subject: [PATCH 63/67] 8062521: 9-dev glinux/elinux "configure: error: Could not find all X11 headers" since 2014-10-28 Reviewed-by: dholmes --- common/autoconf/flags.m4 | 4 ++-- common/autoconf/generated-configure.sh | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/autoconf/flags.m4 b/common/autoconf/flags.m4 index 7a62d93ea7f..cd2d4a38eaa 100644 --- a/common/autoconf/flags.m4 +++ b/common/autoconf/flags.m4 @@ -136,8 +136,8 @@ AC_DEFUN_ONCE([FLAGS_SETUP_INIT_FLAGS], SYSROOT_CFLAGS="-isysroot \"$SYSROOT\" -iframework\"$SYSROOT/System/Library/Frameworks\"" SYSROOT_LDFLAGS=$SYSROOT_CFLAGS elif test "x$TOOLCHAIN_TYPE" = xgcc; then - SYSROOT_CFLAGS="--sysroot=\"$SYSROOT\"" - SYSROOT_LDFLAGS="--sysroot=\"$SYSROOT\"" + SYSROOT_CFLAGS="--sysroot=$SYSROOT" + SYSROOT_LDFLAGS="--sysroot=$SYSROOT" elif test "x$TOOLCHAIN_TYPE" = xclang; then SYSROOT_CFLAGS="-isysroot \"$SYSROOT\"" SYSROOT_LDFLAGS="-isysroot \"$SYSROOT\"" diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index aae85eec44d..9f89d6eb293 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -4328,7 +4328,7 @@ TOOLCHAIN_DESCRIPTION_xlc="IBM XL C/C++" #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1414485998 +DATE_WHEN_GENERATED=1414663067 ############################################################################### # @@ -41681,8 +41681,8 @@ $as_echo "$tool_specified" >&6; } SYSROOT_CFLAGS="-isysroot \"$SYSROOT\" -iframework\"$SYSROOT/System/Library/Frameworks\"" SYSROOT_LDFLAGS=$SYSROOT_CFLAGS elif test "x$TOOLCHAIN_TYPE" = xgcc; then - SYSROOT_CFLAGS="--sysroot=\"$SYSROOT\"" - SYSROOT_LDFLAGS="--sysroot=\"$SYSROOT\"" + SYSROOT_CFLAGS="--sysroot=$SYSROOT" + SYSROOT_LDFLAGS="--sysroot=$SYSROOT" elif test "x$TOOLCHAIN_TYPE" = xclang; then SYSROOT_CFLAGS="-isysroot \"$SYSROOT\"" SYSROOT_LDFLAGS="-isysroot \"$SYSROOT\"" From 32ca949153c42a66c120b0cdf8dca291f9a2a476 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 30 Oct 2014 11:31:17 -0700 Subject: [PATCH 64/67] 8062501: Modifications of server socket channel accept() methods for instrumentation purposes Wrap accept0() native methods in Java accept(). Reviewed-by: chegar, alanb --- .../sun/nio/ch/ServerSocketChannelImpl.java | 14 +++++++++++++- .../UnixAsynchronousServerSocketChannelImpl.java | 16 ++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java index a7cc1946904..b5b8b05d36f 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java @@ -247,7 +247,7 @@ class ServerSocketChannelImpl return null; thread = NativeThread.current(); for (;;) { - n = accept0(this.fd, newfd, isaa); + n = accept(this.fd, newfd, isaa); if ((n == IOStatus.INTERRUPTED) && isOpen()) continue; break; @@ -410,6 +410,18 @@ class ServerSocketChannelImpl return sb.toString(); } + /** + * Accept a connection on a socket. + * + * @implNote Wrap native call to allow instrumentation. + */ + private int accept(FileDescriptor ssfd, FileDescriptor newfd, + InetSocketAddress[] isaa) + throws IOException + { + return accept0(ssfd, newfd, isaa); + } + // -- Native methods -- // Accepts a new connection, setting the given file descriptor to refer to diff --git a/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java b/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java index 871f19448fa..8c7cfd2291d 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java +++ b/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java @@ -141,7 +141,7 @@ class UnixAsynchronousServerSocketChannelImpl Throwable exc = null; try { begin(); - int n = accept0(this.fd, newfd, isaa); + int n = accept(this.fd, newfd, isaa); // spurious wakeup, is this possible? if (n == IOStatus.UNAVAILABLE) { @@ -277,7 +277,7 @@ class UnixAsynchronousServerSocketChannelImpl try { begin(); - int n = accept0(this.fd, newfd, isaa); + int n = accept(this.fd, newfd, isaa); if (n == IOStatus.UNAVAILABLE) { // need calling context when there is security manager as @@ -332,6 +332,18 @@ class UnixAsynchronousServerSocketChannelImpl } } + /** + * Accept a connection on a socket. + * + * @implNote Wrap native call to allow instrumentation. + */ + private int accept(FileDescriptor ssfd, FileDescriptor newfd, + InetSocketAddress[] isaa) + throws IOException + { + return accept0(ssfd, newfd, isaa); + } + // -- Native methods -- private static native void initIDs(); From 5d33a33e2f7c4cd402ccd3bc85b5ad7be234e071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Thu, 30 Oct 2014 19:55:56 +0100 Subject: [PATCH 65/67] 8062401: User accessors require boxing and do not support optimistic types Reviewed-by: jlaskey, lagergren --- .../internal/codegen/SpillObjectCreator.java | 2 +- .../internal/codegen/TypeEvaluator.java | 2 +- .../internal/objects/NativeObject.java | 2 +- .../internal/runtime/AccessorProperty.java | 56 ++--- .../internal/runtime/FindProperty.java | 10 +- .../nashorn/internal/runtime/Property.java | 47 ++++- .../nashorn/internal/runtime/PropertyMap.java | 2 +- .../internal/runtime/ScriptObject.java | 2 +- .../internal/runtime/SpillProperty.java | 4 +- .../runtime/UserAccessorProperty.java | 194 +++++++++++------- .../internal/runtime/linker/Bootstrap.java | 14 ++ nashorn/test/examples/getter-setter-micro.js | 81 ++++++++ 12 files changed, 287 insertions(+), 129 deletions(-) create mode 100644 nashorn/test/examples/getter-setter-micro.js diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java index 4fa51091b5f..40d12dfbdc2 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java @@ -88,7 +88,7 @@ public final class SpillObjectCreator extends ObjectCreator { final Property property = propertyMap.findProperty(key); if (property != null) { // normal property key - property.setCurrentType(JSType.unboxedFieldType(constantValue)); + property.setType(JSType.unboxedFieldType(constantValue)); final int slot = property.getSlot(); if (!OBJECT_FIELDS_ONLY && constantValue instanceof Number) { jpresetValues[slot] = ObjectClassGenerator.pack((Number)constantValue); diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java index 4f3bc07f1db..d5282a8b9db 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java @@ -117,7 +117,7 @@ final class TypeEvaluator { } final Property property = find.getProperty(); - final Class propertyClass = property.getCurrentType(); + final Class propertyClass = property.getType(); if (propertyClass == null) { // propertyClass == null means its value is Undefined. It is probably not initialized yet, so we won't make // a type assumption yet. diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeObject.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeObject.java index dcd7587bab0..7a1375d39e2 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeObject.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeObject.java @@ -672,7 +672,7 @@ public final class NativeObject { for (final Property prop : properties) { if (prop.isEnumerable()) { final Object value = sourceObj.get(prop.getKey()); - prop.setCurrentType(Object.class); + prop.setType(Object.class); prop.setValue(sourceObj, sourceObj, value, false); propList.add(prop); } diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java index e29353683c0..a9afeb93abf 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java @@ -144,13 +144,6 @@ public class AccessorProperty extends Property { /** Seed setter for the Object version of this field */ transient MethodHandle objectSetter; - /** - * Current type of this object, in object only mode, this is an Object.class. In dual-fields mode - * null means undefined, and primitive types are allowed. The reason a special type is used for - * undefined, is that are no bits left to represent it in primitive types - */ - private Class currentType; - /** * Delegate constructor for bound properties. This is used for properties created by * {@link ScriptRuntime#mergeScope} and the Nashorn {@code Object.bindProperties} method. @@ -171,7 +164,7 @@ public class AccessorProperty extends Property { this.objectSetter = bindTo(property.objectSetter, delegate); property.GETTER_CACHE = new MethodHandle[NOOF_TYPES]; // Properties created this way are bound to a delegate - setCurrentType(property.getCurrentType()); + setType(property.getType()); } /** @@ -248,7 +241,7 @@ public class AccessorProperty extends Property { objectGetter = getter.type() != Lookup.GET_OBJECT_TYPE ? MH.asType(getter, Lookup.GET_OBJECT_TYPE) : getter; objectSetter = setter != null && setter.type() != Lookup.SET_OBJECT_TYPE ? MH.asType(setter, Lookup.SET_OBJECT_TYPE) : setter; - setCurrentType(OBJECT_FIELDS_ONLY ? Object.class : getterType); + setType(OBJECT_FIELDS_ONLY ? Object.class : getterType); } /** @@ -317,7 +310,7 @@ public class AccessorProperty extends Property { */ public AccessorProperty(final String key, final int flags, final Class structure, final int slot, final Class initialType) { this(key, flags, structure, slot); - setCurrentType(OBJECT_FIELDS_ONLY ? Object.class : initialType); + setType(OBJECT_FIELDS_ONLY ? Object.class : initialType); } /** @@ -330,13 +323,13 @@ public class AccessorProperty extends Property { protected AccessorProperty(final AccessorProperty property, final Class newType) { super(property, property.getFlags()); - this.GETTER_CACHE = newType != property.getCurrentType() ? new MethodHandle[NOOF_TYPES] : property.GETTER_CACHE; + this.GETTER_CACHE = newType != property.getLocalType() ? new MethodHandle[NOOF_TYPES] : property.GETTER_CACHE; this.primitiveGetter = property.primitiveGetter; this.primitiveSetter = property.primitiveSetter; this.objectGetter = property.objectGetter; this.objectSetter = property.objectSetter; - setCurrentType(newType); + setType(newType); } /** @@ -345,7 +338,7 @@ public class AccessorProperty extends Property { * @param property source property */ protected AccessorProperty(final AccessorProperty property) { - this(property, property.getCurrentType()); + this(property, property.getLocalType()); } /** @@ -354,7 +347,7 @@ public class AccessorProperty extends Property { * @param initialValue initial value */ protected final void setInitialValue(final ScriptObject owner, final Object initialValue) { - setCurrentType(JSType.unboxedFieldType(initialValue)); + setType(JSType.unboxedFieldType(initialValue)); if (initialValue instanceof Integer) { invokeSetter(owner, ((Integer)initialValue).intValue()); } else if (initialValue instanceof Long) { @@ -370,7 +363,7 @@ public class AccessorProperty extends Property { * Initialize the type of a property */ protected final void initializeType() { - setCurrentType(OBJECT_FIELDS_ONLY ? Object.class : null); + setType(OBJECT_FIELDS_ONLY ? Object.class : null); } private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException { @@ -557,12 +550,12 @@ public class AccessorProperty extends Property { } else { getter = debug( createGetter( - getCurrentType(), + getLocalType(), type, primitiveGetter, objectGetter, INVALID_PROGRAM_POINT), - getCurrentType(), + getLocalType(), type, "get"); getterCache[i] = getter; @@ -582,18 +575,18 @@ public class AccessorProperty extends Property { return debug( createGetter( - getCurrentType(), + getLocalType(), type, primitiveGetter, objectGetter, programPoint), - getCurrentType(), + getLocalType(), type, "get"); } private MethodHandle getOptimisticPrimitiveGetter(final Class type, final int programPoint) { - final MethodHandle g = getGetter(getCurrentType()); + final MethodHandle g = getGetter(getLocalType()); return MH.asType(OptimisticReturnFilters.filterOptimisticReturnValue(g, type, programPoint), g.type().changeReturnType(type)); } @@ -631,7 +624,7 @@ public class AccessorProperty extends Property { } private MethodHandle generateSetter(final Class forType, final Class type) { - return debug(createSetter(forType, type, primitiveSetter, objectSetter), getCurrentType(), type, "set"); + return debug(createSetter(forType, type, primitiveSetter, objectSetter), getLocalType(), type, "set"); } /** @@ -639,7 +632,7 @@ public class AccessorProperty extends Property { * @return true if undefined */ protected final boolean isUndefined() { - return getCurrentType() == null; + return getLocalType() == null; } @Override @@ -647,7 +640,7 @@ public class AccessorProperty extends Property { checkUndeclared(); final int typeIndex = getAccessorTypeIndex(type); - final int currentTypeIndex = getAccessorTypeIndex(getCurrentType()); + final int currentTypeIndex = getAccessorTypeIndex(getLocalType()); //if we are asking for an object setter, but are still a primitive type, we might try to box it MethodHandle mh; @@ -656,13 +649,13 @@ public class AccessorProperty extends Property { final PropertyMap newMap = getWiderMap(currentMap, newProperty); final MethodHandle widerSetter = newProperty.getSetter(type, newMap); - final Class ct = getCurrentType(); + final Class ct = getLocalType(); mh = MH.filterArguments(widerSetter, 0, MH.insertArguments(debugReplace(ct, type, currentMap, newMap) , 1, newMap)); if (ct != null && ct.isPrimitive() && !type.isPrimitive()) { mh = ObjectClassGenerator.createGuardBoxedPrimitiveSetter(ct, generateSetter(ct, ct), mh); } } else { - final Class forType = isUndefined() ? type : getCurrentType(); + final Class forType = isUndefined() ? type : getLocalType(); mh = generateSetter(!forType.isPrimitive() ? Object.class : forType, type); } @@ -681,24 +674,13 @@ public class AccessorProperty extends Property { return false; } // Return true for currently undefined even if non-writable/configurable to allow initialization of ES6 CONST. - return getCurrentType() == null || (getCurrentType() != Object.class && (isConfigurable() || isWritable())); + return getLocalType() == null || (getLocalType() != Object.class && (isConfigurable() || isWritable())); } private boolean needsInvalidator(final int typeIndex, final int currentTypeIndex) { return canChangeType() && typeIndex > currentTypeIndex; } - @Override - public final void setCurrentType(final Class currentType) { - assert currentType != boolean.class : "no boolean storage support yet - fix this"; - this.currentType = currentType == null ? null : currentType.isPrimitive() ? currentType : Object.class; - } - - @Override - public Class getCurrentType() { - return currentType; - } - private MethodHandle debug(final MethodHandle mh, final Class forType, final Class type, final String tag) { if (!Context.DEBUG || !Global.hasInstance()) { return mh; diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FindProperty.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FindProperty.java index b4e00124837..3b153c58a29 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FindProperty.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FindProperty.java @@ -84,13 +84,18 @@ public final class FindProperty { * @return method handle for the getter */ public MethodHandle getGetter(final Class type, final int programPoint, final LinkRequest request) { - final MethodHandle getter; + MethodHandle getter; if (isValid(programPoint)) { getter = property.getOptimisticGetter(type, programPoint); } else { getter = property.getGetter(type); } if (property instanceof UserAccessorProperty) { + getter = MH.insertArguments(getter, 1, UserAccessorProperty.getINVOKE_UA_GETTER(type, programPoint)); + if (isValid(programPoint) && type.isPrimitive()) { + getter = MH.insertArguments(getter, 1, programPoint); + } + property.setType(type); return insertAccessorsGetter((UserAccessorProperty) property, request, getter); } return getter; @@ -111,7 +116,8 @@ public final class FindProperty { public MethodHandle getSetter(final Class type, final boolean strict, final LinkRequest request) { MethodHandle setter = property.getSetter(type, getOwner().getMap()); if (property instanceof UserAccessorProperty) { - setter = MH.insertArguments(setter, 1, strict ? property.getKey() : null); + setter = MH.insertArguments(setter, 1, UserAccessorProperty.getINVOKE_UA_SETTER(type), strict ? property.getKey() : null); + property.setType(type); return insertAccessorsGetter((UserAccessorProperty) property, request, setter); } diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java index f57246cacad..41baa64243b 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java @@ -102,6 +102,13 @@ public abstract class Property implements Serializable { /** Property field number or spill slot. */ private final int slot; + /** + * Current type of this object, in object only mode, this is an Object.class. In dual-fields mode + * null means undefined, and primitive types are allowed. The reason a special type is used for + * undefined, is that are no bits left to represent it in primitive types + */ + private Class type; + /** SwitchPoint that is invalidated when property is changed, optional */ protected transient SwitchPoint builtinSwitchPoint; @@ -536,7 +543,7 @@ public abstract class Property implements Serializable { *

* see {@link ObjectClassGenerator#createSetter(Class, Class, MethodHandle, MethodHandle)} * if you are interested in the internal details of this. Note that if you - * are running in default mode, with {@code -Dnashorn.fields.dual=true}, disabled, the setters + * are running with {@code -Dnashorn.fields.objects=true}, the setters * will currently never change, as all properties are represented as Object field, * the Object fields are Initialized to {@code ScriptRuntime.UNDEFINED} and primitives are * boxed/unboxed upon every access, which is not necessarily optimal @@ -569,7 +576,7 @@ public abstract class Property implements Serializable { @Override public int hashCode() { - final Class type = getCurrentType(); + final Class type = getLocalType(); return Objects.hashCode(this.key) ^ flags ^ getSlot() ^ (type == null ? 0 : type.hashCode()); } @@ -586,7 +593,7 @@ public abstract class Property implements Serializable { final Property otherProperty = (Property)other; return equalsWithoutType(otherProperty) && - getCurrentType() == otherProperty.getCurrentType(); + getLocalType() == otherProperty.getLocalType(); } boolean equalsWithoutType(final Property otherProperty) { @@ -615,7 +622,7 @@ public abstract class Property implements Serializable { */ public final String toStringShort() { final StringBuilder sb = new StringBuilder(); - final Class type = getCurrentType(); + final Class type = getLocalType(); sb.append(getKey()).append(" (").append(type(type)).append(')'); return sb.toString(); } @@ -632,7 +639,7 @@ public abstract class Property implements Serializable { @Override public String toString() { final StringBuilder sb = new StringBuilder(); - final Class type = getCurrentType(); + final Class type = getLocalType(); sb.append(indent(getKey(), 20)). append(" id="). @@ -656,20 +663,40 @@ public abstract class Property implements Serializable { } /** - * Get the current type of this field. If you are not running with dual fields enabled, + * Get the current type of this property. If you are running with object fields enabled, * this will always be Object.class. See the value representation explanation in * {@link Property#getSetter(Class, PropertyMap)} and {@link ObjectClassGenerator} * for more information. * + *

Note that for user accessor properties, this returns the type of the last observed + * value passed to or returned by a user accessor. Use {@link #getLocalType()} to always get + * the type of the actual value stored in the property slot.

+ * * @return current type of property, null means undefined */ - public abstract Class getCurrentType(); + public final Class getType() { + return type; + } /** - * Reset the current type of this property - * @param currentType new current type + * Set the type of this property. + * @param type new type */ - public abstract void setCurrentType(final Class currentType); + public final void setType(final Class type) { + assert type != boolean.class : "no boolean storage support yet - fix this"; + this.type = type == null ? null : type.isPrimitive() ? type : Object.class; + } + + /** + * Get the type of the value in the local property slot. This returns the same as + * {@link #getType()} for normal properties, but always returns {@code Object.class} + * for {@link UserAccessorProperty}s as their local type is a pair of accessor references. + * + * @return the local property type + */ + protected Class getLocalType() { + return getType(); + } /** * Check whether this Property can ever change its type. The default is false, and if diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java index 61912332fc8..defd305b30b 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java @@ -512,7 +512,7 @@ public final class PropertyMap implements Iterable, Serializable { assert sameType || oldProperty instanceof AccessorProperty && newProperty instanceof UserAccessorProperty : - "arbitrary replaceProperty attempted " + sameType + " oldProperty=" + oldProperty.getClass() + " newProperty=" + newProperty.getClass() + " [" + oldProperty.getCurrentType() + " => " + newProperty.getCurrentType() + "]"; + "arbitrary replaceProperty attempted " + sameType + " oldProperty=" + oldProperty.getClass() + " newProperty=" + newProperty.getClass() + " [" + oldProperty.getLocalType() + " => " + newProperty.getLocalType() + "]"; newMap.flags = flags; diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java index da1023eddd9..a76703cf1bf 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java @@ -969,7 +969,7 @@ public abstract class ScriptObject implements PropertyAccess { final UserAccessorProperty uc = (UserAccessorProperty)oldProperty; final int slot = uc.getSlot(); - assert uc.getCurrentType() == Object.class; + assert uc.getLocalType() == Object.class; if (slot >= spillLength) { uc.setAccessors(this, getMap(), new UserAccessorProperty.Accessors(getter, setter)); } else { diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SpillProperty.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SpillProperty.java index 8ff1b8e5ef6..7b42b2bfa30 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SpillProperty.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SpillProperty.java @@ -161,12 +161,12 @@ public class SpillProperty extends AccessorProperty { */ public SpillProperty(final String key, final int flags, final int slot) { super(key, flags, slot, primitiveGetter(slot), primitiveSetter(slot), objectGetter(slot), objectSetter(slot)); - assert !OBJECT_FIELDS_ONLY || getCurrentType() == Object.class; + assert !OBJECT_FIELDS_ONLY || getLocalType() == Object.class; } SpillProperty(final String key, final int flags, final int slot, final Class initialType) { this(key, flags, slot); - setCurrentType(OBJECT_FIELDS_ONLY ? Object.class : initialType); + setType(OBJECT_FIELDS_ONLY ? Object.class : initialType); } SpillProperty(final String key, final int flags, final int slot, final ScriptObject owner, final Object initialValue) { diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/UserAccessorProperty.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/UserAccessorProperty.java index 5fdec0094a3..d14dd8e701f 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/UserAccessorProperty.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/UserAccessorProperty.java @@ -27,16 +27,16 @@ package jdk.nashorn.internal.runtime; import static jdk.nashorn.internal.lookup.Lookup.MH; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; -import static jdk.nashorn.internal.runtime.JSType.CONVERT_OBJECT_OPTIMISTIC; -import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; +import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; -import java.util.concurrent.Callable; import jdk.nashorn.internal.lookup.Lookup; import jdk.nashorn.internal.runtime.linker.Bootstrap; +import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; /** * Property with user defined getters/setters. Actual getter and setter @@ -69,38 +69,29 @@ public final class UserAccessorProperty extends SpillProperty { private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); /** Getter method handle */ - private final static MethodHandle INVOKE_GETTER_ACCESSOR = findOwnMH_S("invokeGetterAccessor", Object.class, Accessors.class, Object.class); + private final static MethodHandle INVOKE_OBJECT_GETTER = findOwnMH_S("invokeObjectGetter", Object.class, Accessors.class, MethodHandle.class, Object.class); + private final static MethodHandle INVOKE_INT_GETTER = findOwnMH_S("invokeIntGetter", int.class, Accessors.class, MethodHandle.class, int.class, Object.class); + private final static MethodHandle INVOKE_LONG_GETTER = findOwnMH_S("invokeLongGetter", long.class, Accessors.class, MethodHandle.class, int.class, Object.class); + private final static MethodHandle INVOKE_NUMBER_GETTER = findOwnMH_S("invokeNumberGetter", double.class, Accessors.class, MethodHandle.class, int.class, Object.class); /** Setter method handle */ - private final static MethodHandle INVOKE_SETTER_ACCESSOR = findOwnMH_S("invokeSetterAccessor", void.class, Accessors.class, String.class, Object.class, Object.class); + private final static MethodHandle INVOKE_OBJECT_SETTER = findOwnMH_S("invokeObjectSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, Object.class); + private final static MethodHandle INVOKE_INT_SETTER = findOwnMH_S("invokeIntSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, int.class); + private final static MethodHandle INVOKE_LONG_SETTER = findOwnMH_S("invokeLongSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, long.class); + private final static MethodHandle INVOKE_NUMBER_SETTER = findOwnMH_S("invokeNumberSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, double.class); - /** Dynamic invoker for getter */ - private static final Object GETTER_INVOKER_KEY = new Object(); - private static MethodHandle getINVOKE_UA_GETTER() { - - return Context.getGlobal().getDynamicInvoker(GETTER_INVOKER_KEY, - new Callable() { - @Override - public MethodHandle call() { - return Bootstrap.createDynamicInvoker("dyn:call", Object.class, - Object.class, Object.class); - } - }); + static MethodHandle getINVOKE_UA_GETTER(final Class returnType, final int programPoint) { + if (UnwarrantedOptimismException.isValid(programPoint)) { + final int flags = NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC | programPoint << CALLSITE_PROGRAM_POINT_SHIFT; + return Bootstrap.createDynamicInvoker("dyn:call", flags, returnType, Object.class, Object.class); + } else { + return Bootstrap.createDynamicInvoker("dyn:call", Object.class, Object.class, Object.class); + } } - /** Dynamic invoker for setter */ - private static Object SETTER_INVOKER_KEY = new Object(); - - private static MethodHandle getINVOKE_UA_SETTER() { - return Context.getGlobal().getDynamicInvoker(SETTER_INVOKER_KEY, - new Callable() { - @Override - public MethodHandle call() { - return Bootstrap.createDynamicInvoker("dyn:call", void.class, - Object.class, Object.class, Object.class); - } - }); + static MethodHandle getINVOKE_UA_SETTER(final Class valueType) { + return Bootstrap.createDynamicInvoker("dyn:call", void.class, Object.class, Object.class, valueType); } /** @@ -158,7 +149,7 @@ public final class UserAccessorProperty extends SpillProperty { } @Override - public Class getCurrentType() { + protected Class getLocalType() { return Object.class; } @@ -189,7 +180,13 @@ public final class UserAccessorProperty extends SpillProperty { @Override public Object getObjectValue(final ScriptObject self, final ScriptObject owner) { - return invokeGetterAccessor(getAccessors((owner != null) ? owner : self), self); + try { + return invokeObjectGetter(getAccessors((owner != null) ? owner : self), getINVOKE_UA_GETTER(Object.class, INVALID_PROGRAM_POINT), self); + } catch (final Error | RuntimeException t) { + throw t; + } catch (final Throwable t) { + throw new RuntimeException(t); + } } @Override @@ -209,41 +206,33 @@ public final class UserAccessorProperty extends SpillProperty { @Override public void setValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) { - invokeSetterAccessor(getAccessors((owner != null) ? owner : self), strict ? getKey() : null, self, value); + try { + invokeObjectSetter(getAccessors((owner != null) ? owner : self), getINVOKE_UA_SETTER(Object.class), strict ? getKey() : null, self, value); + } catch (final Error | RuntimeException t) { + throw t; + } catch (final Throwable t) { + throw new RuntimeException(t); + } } @Override public MethodHandle getGetter(final Class type) { //this returns a getter on the format (Accessors, Object receiver) - return Lookup.filterReturnType(INVOKE_GETTER_ACCESSOR, type); + return Lookup.filterReturnType(INVOKE_OBJECT_GETTER, type); } @Override public MethodHandle getOptimisticGetter(final Class type, final int programPoint) { - //fortype is always object, but in the optimistic world we have to throw - //unwarranted optimism exception for narrower types. We can improve this - //by checking for boxed types and unboxing them, but it is doubtful that - //this gives us any performance, as UserAccessorProperties are typically not - //primitives. Are there? TODO: investigate later. For now we just throw an - //exception for narrower types than object - - if (type.isPrimitive()) { - final MethodHandle getter = getGetter(Object.class); - final MethodHandle mh = - MH.asType( - MH.filterReturnValue( - getter, - MH.insertArguments( - CONVERT_OBJECT_OPTIMISTIC.get(getAccessorTypeIndex(type)), - 1, - programPoint)), - getter.type().changeReturnType(type)); - - return mh; + if (type == int.class) { + return INVOKE_INT_GETTER; + } else if (type == long.class) { + return INVOKE_LONG_GETTER; + } else if (type == double.class) { + return INVOKE_NUMBER_GETTER; + } else { + assert type == Object.class; + return INVOKE_OBJECT_GETTER; } - - assert type == Object.class; - return getGetter(type); } @Override @@ -259,7 +248,16 @@ public final class UserAccessorProperty extends SpillProperty { @Override public MethodHandle getSetter(final Class type, final PropertyMap currentMap) { - return INVOKE_SETTER_ACCESSOR; + if (type == int.class) { + return INVOKE_INT_SETTER; + } else if (type == long.class) { + return INVOKE_LONG_SETTER; + } else if (type == double.class) { + return INVOKE_NUMBER_SETTER; + } else { + assert type == Object.class; + return INVOKE_OBJECT_SETTER; + } } @Override @@ -282,31 +280,81 @@ public final class UserAccessorProperty extends SpillProperty { // getter/setter may be inherited. If so, proto is bound during lookup. In either // inherited or self case, slot is also bound during lookup. Actual ScriptFunction // to be called is retrieved everytime and applied. - private static Object invokeGetterAccessor(final Accessors gs, final Object self) { + @SuppressWarnings("unused") + private static Object invokeObjectGetter(final Accessors gs, final MethodHandle invoker, final Object self) throws Throwable { final Object func = gs.getter; if (func instanceof ScriptFunction) { - try { - return getINVOKE_UA_GETTER().invokeExact(func, self); - } catch (final Error | RuntimeException t) { - throw t; - } catch (final Throwable t) { - throw new RuntimeException(t); - } + return invoker.invokeExact(func, self); } return UNDEFINED; } - private static void invokeSetterAccessor(final Accessors gs, final String name, final Object self, final Object value) { + @SuppressWarnings("unused") + private static int invokeIntGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable { + final Object func = gs.getter; + if (func instanceof ScriptFunction) { + return (int) invoker.invokeExact(func, self); + } + + throw new UnwarrantedOptimismException(UNDEFINED, programPoint); + } + + @SuppressWarnings("unused") + private static long invokeLongGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable { + final Object func = gs.getter; + if (func instanceof ScriptFunction) { + return (long) invoker.invokeExact(func, self); + } + + throw new UnwarrantedOptimismException(UNDEFINED, programPoint); + } + + @SuppressWarnings("unused") + private static double invokeNumberGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable { + final Object func = gs.getter; + if (func instanceof ScriptFunction) { + return (double) invoker.invokeExact(func, self); + } + + throw new UnwarrantedOptimismException(UNDEFINED, programPoint); + } + + @SuppressWarnings("unused") + private static void invokeObjectSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final Object value) throws Throwable { final Object func = gs.setter; if (func instanceof ScriptFunction) { - try { - getINVOKE_UA_SETTER().invokeExact(func, self, value); - } catch (final Error | RuntimeException t) { - throw t; - } catch (final Throwable t) { - throw new RuntimeException(t); - } + invoker.invokeExact(func, self, value); + } else if (name != null) { + throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self)); + } + } + + @SuppressWarnings("unused") + private static void invokeIntSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final int value) throws Throwable { + final Object func = gs.setter; + if (func instanceof ScriptFunction) { + invoker.invokeExact(func, self, value); + } else if (name != null) { + throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self)); + } + } + + @SuppressWarnings("unused") + private static void invokeLongSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final long value) throws Throwable { + final Object func = gs.setter; + if (func instanceof ScriptFunction) { + invoker.invokeExact(func, self, value); + } else if (name != null) { + throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self)); + } + } + + @SuppressWarnings("unused") + private static void invokeNumberSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final double value) throws Throwable { + final Object func = gs.setter; + if (func instanceof ScriptFunction) { + invoker.invokeExact(func, self, value); } else if (name != null) { throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self)); } diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java index 67dd88e2c49..a0842f2d166 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java @@ -335,6 +335,20 @@ public final class Bootstrap { return createDynamicInvoker(opDesc, MethodType.methodType(rtype, ptypes)); } + /** + * Returns a dynamic invoker for a specified dynamic operation using the public lookup. Similar to + * {@link #createDynamicInvoker(String, Class, Class...)} but with an additional parameter to + * set the call site flags of the dynamic invoker. + * @param opDesc Dynalink dynamic operation descriptor. + * @param flags the call site flags for the operation + * @param rtype the return type for the operation + * @param ptypes the parameter types for the operation + * @return MethodHandle for invoking the operation. + */ + public static MethodHandle createDynamicInvoker(final String opDesc, final int flags, final Class rtype, final Class... ptypes) { + return bootstrap(MethodHandles.publicLookup(), opDesc, MethodType.methodType(rtype, ptypes), flags).dynamicInvoker(); + } + /** * Returns a dynamic invoker for a specified dynamic operation using the public lookup. Similar to * {@link #createDynamicInvoker(String, Class, Class...)} but with return and parameter types composed into a diff --git a/nashorn/test/examples/getter-setter-micro.js b/nashorn/test/examples/getter-setter-micro.js new file mode 100644 index 00000000000..68ed1c302e2 --- /dev/null +++ b/nashorn/test/examples/getter-setter-micro.js @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * A micro-benchmark for getters and setters with primitive values, + * alternating between ints and doubles. Introduction of primitive + * and optimistic user accessors in JDK-8062401 make this faster by + * 10x or more by allowing inlining and other optimizations to take place. + */ + +var x = { + get m() { + return this._m; + }, + set m(v) { + this._m = v; + }, + get n() { + return this._n; + }, + set n(v) { + this._n = v; + } +}; + + +function bench(v1, v2, result) { + var start = Date.now(); + x.n = v1; + for (var i = 0; i < 1e8; i++) { + x.m = v2; + if (x.m + x.n !== result) { + throw "wrong result"; + } + } + print("done in", Date.now() - start, "millis"); +} + +for (var i = 0; i < 10; i++) { + bench(i, 4, 4 + i); +} + +for (var i = 0; i < 10; i++) { + bench(i, 4.5, 4.5 + i); +} + +for (var i = 0; i < 10; i++) { + bench(i, 5, 5 + i); +} + +for (var i = 0; i < 10; i++) { + bench(i, 5.5, 5.5 + i); +} From 35b29e76622e1dc126429ed3a0bf9246056d9b94 Mon Sep 17 00:00:00 2001 From: Sonali Goel Date: Thu, 30 Oct 2014 15:21:42 -0700 Subject: [PATCH 66/67] 8062336: Revert tools/javap/T6729471.java to original test code Reviewed-by: jjg --- langtools/test/tools/javap/T6729471.java | 39 ++++++++++++------------ 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/langtools/test/tools/javap/T6729471.java b/langtools/test/tools/javap/T6729471.java index 9aa49ce35dc..5fdb368885b 100644 --- a/langtools/test/tools/javap/T6729471.java +++ b/langtools/test/tools/javap/T6729471.java @@ -25,10 +25,7 @@ /* * @test * @bug 6729471 - * @summary javap should accept class files on the command line - * @library /tools/lib - * @build ToolBox - * @run main T6729471 + * @summary javap does not output inner interfaces of an interface */ import java.io.*; @@ -60,26 +57,30 @@ public class T6729471 verify(new File(testClasses, "T6729471.class").toURI().toString(), "public static void main(java.lang.String...)"); - // jar url - // Create a temp jar - ToolBox tb = new ToolBox(); - tb.new JavacTask() - .sources("class Foo { public void sayHello() {} }") - .run(); - String foo_jar = "foo.jar"; - tb.new JarTask(foo_jar) - .files("Foo.class") - .run(); - File foo_jarFile = new File(foo_jar); - - // Verify + // jar url: rt.jar + File java_home = new File(System.getProperty("java.home")); + if (java_home.getName().equals("jre")) + java_home = java_home.getParentFile(); + File rt_jar = new File(new File(new File(java_home, "jre"), "lib"), "rt.jar"); try { - verify("jar:" + foo_jarFile.toURL() + "!/Foo.class", - "public void sayHello()"); + verify("jar:" + rt_jar.toURL() + "!/java/util/Map.class", + "public abstract boolean containsKey(java.lang.Object)"); } catch (MalformedURLException e) { error(e.toString()); } + // jar url: ct.sym, if it exists + File ct_sym = new File(new File(java_home, "lib"), "ct.sym"); + if (ct_sym.exists()) { + try { + verify("jar:" + ct_sym.toURL() + "!/META-INF/sym/rt.jar/java/util/Map.class", + "public abstract boolean containsKey(java.lang.Object)"); + } catch (MalformedURLException e) { + error(e.toString()); + } + } else + System.err.println("warning: ct.sym not found"); + if (errors > 0) throw new Error(errors + " found."); } From 2bb2dec6335e9e467d21d26b679030bbacfed6a6 Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 20:05:31 +0200 Subject: [PATCH 67/67] Added tag jdk9-b37 for changeset b409bc51bc23 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index c3c1023b5e6..eebf56d77af 100644 --- a/.hgtags +++ b/.hgtags @@ -279,3 +279,4 @@ f0c5e4b732da823bdaa4184133675f384e7cd68d jdk9-b33 9618201c5df28a460631577fad1f61e96f775c34 jdk9-b34 a137992d750c72f6f944f341aa19b0d0d96afe0c jdk9-b35 41df50e7303daf73c0d661ef601c4fe250915de5 jdk9-b36 +b409bc51bc23cfd51f2bd04ea919ec83535af9d0 jdk9-b37