From 94bafe8b8f1d219c38840dd076b6c7f96f5f6dda Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Tue, 18 Aug 2009 12:10:12 +0800 Subject: [PATCH 001/172] 6864911: ASN.1/DER input stream parser needs more work Reviewed-by: mullan, xuelei --- .../classes/com/sun/jndi/ldap/Connection.java | 28 ++--- .../classes/sun/applet/AppletClassLoader.java | 34 +---- .../sun/dyn/anon/AnonymousClassLoader.java | 11 +- jdk/src/share/classes/sun/misc/IOUtils.java | 80 ++++++++++++ jdk/src/share/classes/sun/misc/Resource.java | 71 +++++------ .../classes/sun/reflect/misc/MethodUtil.java | 32 +---- .../provider/certpath/OCSPChecker.java | 22 +--- .../security/timestamp/HttpTimestamper.java | 21 +--- .../classes/sun/security/util/DerValue.java | 7 +- .../sun/security/util/DerValue/BadValue.java | 119 ++++++++++++++++++ 10 files changed, 251 insertions(+), 174 deletions(-) create mode 100644 jdk/src/share/classes/sun/misc/IOUtils.java create mode 100644 jdk/test/sun/security/util/DerValue/BadValue.java diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java index 2807e19d36f..364f000c839 100644 --- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java +++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, 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 @@ -32,12 +32,8 @@ import java.io.IOException; import java.io.OutputStream; import java.io.InputStream; import java.net.Socket; -import java.util.Vector; -import java.util.Hashtable; import javax.naming.CommunicationException; -import javax.naming.AuthenticationException; -import javax.naming.AuthenticationNotSupportedException; import javax.naming.ServiceUnavailableException; import javax.naming.NamingException; import javax.naming.InterruptedNamingException; @@ -47,6 +43,8 @@ import javax.naming.ldap.Control; import java.lang.reflect.Method; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import sun.misc.IOUtils; //import javax.net.SocketFactory; /** @@ -799,7 +797,6 @@ public final class Connection implements Runnable { byte inbuf[]; // Buffer for reading incoming bytes int inMsgId; // Message id of incoming response int bytesread; // Number of bytes in inbuf - int bytesleft; // Number of bytes that need to read for completing resp int br; // Temp; number of bytes read from stream int offset; // Offset of where to store bytes in inbuf int seqlen; // Length of ASN sequence @@ -811,7 +808,7 @@ public final class Connection implements Runnable { try { while (true) { try { - inbuf = new byte[2048]; + inbuf = new byte[10]; offset = 0; seqlen = 0; @@ -871,19 +868,10 @@ public final class Connection implements Runnable { } // read in seqlen bytes - bytesleft = seqlen; - if ((offset + bytesleft) > inbuf.length) { - byte nbuf[] = new byte[offset + bytesleft]; - System.arraycopy(inbuf, 0, nbuf, 0, offset); - inbuf = nbuf; - } - while (bytesleft > 0) { - bytesread = in.read(inbuf, offset, bytesleft); - if (bytesread < 0) - break; // EOF - offset += bytesread; - bytesleft -= bytesread; - } + byte[] left = IOUtils.readFully(in, seqlen, false); + inbuf = Arrays.copyOf(inbuf, offset + left.length); + System.arraycopy(left, 0, inbuf, offset, left.length); + offset += left.length; /* if (dump > 0) { System.err.println("seqlen: " + seqlen); diff --git a/jdk/src/share/classes/sun/applet/AppletClassLoader.java b/jdk/src/share/classes/sun/applet/AppletClassLoader.java index 3489256ae4a..0eeba1582dd 100644 --- a/jdk/src/share/classes/sun/applet/AppletClassLoader.java +++ b/jdk/src/share/classes/sun/applet/AppletClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2009 Sun Microsystems, 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 @@ -51,6 +51,7 @@ import java.security.Permission; import java.security.PermissionCollection; import sun.awt.AppContext; import sun.awt.SunToolkit; +import sun.misc.IOUtils; import sun.net.www.ParseUtil; import sun.security.util.SecurityConstants; @@ -331,36 +332,7 @@ public class AppletClassLoader extends URLClassLoader { byte[] b; try { - if (len != -1) { - // Read exactly len bytes from the input stream - b = new byte[len]; - while (len > 0) { - int n = in.read(b, b.length - len, len); - if (n == -1) { - throw new IOException("unexpected EOF"); - } - len -= n; - } - } else { - // Read until end of stream is reached - use 8K buffer - // to speed up performance [stanleyh] - b = new byte[8192]; - int total = 0; - while ((len = in.read(b, total, b.length - total)) != -1) { - total += len; - if (total >= b.length) { - byte[] tmp = new byte[total * 2]; - System.arraycopy(b, 0, tmp, 0, total); - b = tmp; - } - } - // Trim array to correct size, if necessary - if (total != b.length) { - byte[] tmp = new byte[total]; - System.arraycopy(b, 0, tmp, 0, total); - b = tmp; - } - } + b = IOUtils.readFully(in, len, true); } finally { in.close(); } diff --git a/jdk/src/share/classes/sun/dyn/anon/AnonymousClassLoader.java b/jdk/src/share/classes/sun/dyn/anon/AnonymousClassLoader.java index a182161271b..5515d93c423 100644 --- a/jdk/src/share/classes/sun/dyn/anon/AnonymousClassLoader.java +++ b/jdk/src/share/classes/sun/dyn/anon/AnonymousClassLoader.java @@ -26,9 +26,9 @@ package sun.dyn.anon; import java.io.IOException; -import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import sun.misc.IOUtils; /** * Anonymous class loader. Will load any valid classfile, producing @@ -285,13 +285,6 @@ public class AnonymousClassLoader { if (contentLength < 0) throw new IOException("invalid content length "+contentLength); - byte[] classFile = new byte[contentLength]; - InputStream tcs = connection.getInputStream(); - for (int fill = 0, nr; fill < classFile.length; fill += nr) { - nr = tcs.read(classFile, fill, classFile.length - fill); - if (nr < 0) - throw new IOException("premature end of file"); - } - return classFile; + return IOUtils.readFully(connection.getInputStream(), contentLength, true); } } diff --git a/jdk/src/share/classes/sun/misc/IOUtils.java b/jdk/src/share/classes/sun/misc/IOUtils.java new file mode 100644 index 00000000000..c6f4fb2a13b --- /dev/null +++ b/jdk/src/share/classes/sun/misc/IOUtils.java @@ -0,0 +1,80 @@ +/* + * Copyright 2009 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * IOUtils: A collection of IO-related public static methods. + */ + +package sun.misc; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; + +public class IOUtils { + + /** + * Read up to length of bytes from in + * until EOF is detected. + * @param in input stream, must not be null + * @param length number of bytes to read, -1 or Integer.MAX_VALUE means + * read as much as possible + * @param readAll if true, an EOFException will be thrown if not enough + * bytes are read. Ignored when length is -1 or Integer.MAX_VALUE + * @return bytes read + * @throws IOException Any IO error or a premature EOF is detected + */ + public static byte[] readFully(InputStream is, int length, boolean readAll) + throws IOException { + byte[] output = {}; + if (length == -1) length = Integer.MAX_VALUE; + int pos = 0; + while (pos < length) { + int bytesToRead; + if (pos >= output.length) { // Only expand when there's no room + bytesToRead = Math.min(length - pos, output.length + 1024); + if (output.length < pos + bytesToRead) { + output = Arrays.copyOf(output, pos + bytesToRead); + } + } else { + bytesToRead = output.length - pos; + } + int cc = is.read(output, pos, bytesToRead); + if (cc < 0) { + if (readAll && length != Integer.MAX_VALUE) { + throw new EOFException("Detect premature EOF"); + } else { + if (output.length != pos) { + output = Arrays.copyOf(output, pos); + } + break; + } + } + pos += cc; + } + return output; + } +} diff --git a/jdk/src/share/classes/sun/misc/Resource.java b/jdk/src/share/classes/sun/misc/Resource.java index 0c3579bc334..43a82b03a70 100644 --- a/jdk/src/share/classes/sun/misc/Resource.java +++ b/jdk/src/share/classes/sun/misc/Resource.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 Sun Microsystems, 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 @@ -25,14 +25,15 @@ package sun.misc; +import java.io.EOFException; import java.net.URL; import java.io.IOException; import java.io.InterruptedIOException; import java.io.InputStream; import java.security.CodeSigner; import java.util.jar.Manifest; -import java.util.jar.Attributes; import java.nio.ByteBuffer; +import java.util.Arrays; import sun.nio.ByteBuffered; /** @@ -105,49 +106,37 @@ public abstract class Resource { } try { - if (len != -1) { - // Read exactly len bytes from the input stream - b = new byte[len]; - while (len > 0) { - int n = 0; - try { - n = in.read(b, b.length - len, len); - } catch (InterruptedIOException iioe) { - Thread.interrupted(); - isInterrupted = true; + b = new byte[0]; + if (len == -1) len = Integer.MAX_VALUE; + int pos = 0; + while (pos < len) { + int bytesToRead; + if (pos >= b.length) { // Only expand when there's no room + bytesToRead = Math.min(len - pos, b.length + 1024); + if (b.length < pos + bytesToRead) { + b = Arrays.copyOf(b, pos + bytesToRead); } - if (n == -1) { - throw new IOException("unexpected EOF"); - } - len -= n; + } else { + bytesToRead = b.length - pos; } - } else { - // Read until end of stream is reached - b = new byte[1024]; - int total = 0; - for (;;) { - len = 0; - try { - len = in.read(b, total, b.length - total); - if (len == -1) - break; - } catch (InterruptedIOException iioe) { - Thread.interrupted(); - isInterrupted = true; - } - total += len; - if (total >= b.length) { - byte[] tmp = new byte[total * 2]; - System.arraycopy(b, 0, tmp, 0, total); - b = tmp; + int cc = 0; + try { + cc = in.read(b, pos, bytesToRead); + } catch (InterruptedIOException iioe) { + Thread.interrupted(); + isInterrupted = true; + } + if (cc < 0) { + if (len != Integer.MAX_VALUE) { + throw new EOFException("Detect premature EOF"); + } else { + if (b.length != pos) { + b = Arrays.copyOf(b, pos); + } + break; } } - // Trim array to correct size, if necessary - if (total != b.length) { - byte[] tmp = new byte[total]; - System.arraycopy(b, 0, tmp, 0, total); - b = tmp; - } + pos += cc; } } finally { try { diff --git a/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java b/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java index 09b14f521d1..39fa2d8afe9 100644 --- a/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java +++ b/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, 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 @@ -44,6 +44,7 @@ import java.lang.reflect.Modifier; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import sun.misc.IOUtils; import sun.net.www.ParseUtil; import sun.security.util.SecurityConstants; @@ -373,34 +374,7 @@ public final class MethodUtil extends SecureClassLoader { byte[] b; try { - if (len != -1) { - // Read exactly len bytes from the input stream - b = new byte[len]; - while (len > 0) { - int n = in.read(b, b.length - len, len); - if (n == -1) { - throw new IOException("unexpected EOF"); - } - len -= n; - } - } else { - b = new byte[8192]; - int total = 0; - while ((len = in.read(b, total, b.length - total)) != -1) { - total += len; - if (total >= b.length) { - byte[] tmp = new byte[total * 2]; - System.arraycopy(b, 0, tmp, 0, total); - b = tmp; - } - } - // Trim array to correct size, if necessary - if (total != b.length) { - byte[] tmp = new byte[total]; - System.arraycopy(b, 0, tmp, 0, total); - b = tmp; - } - } + b = IOUtils.readFully(in, len, true); } finally { in.close(); } diff --git a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java index 04e0649d8ff..b9d246c20b0 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java @@ -37,6 +37,7 @@ import java.security.cert.CertPathValidatorException.BasicReason; import java.net.*; import javax.security.auth.x500.X500Principal; +import sun.misc.IOUtils; import sun.security.util.*; import sun.security.x509.*; @@ -351,27 +352,8 @@ class OCSPChecker extends PKIXCertPathChecker { } in = con.getInputStream(); - byte[] response = null; - int total = 0; int contentLength = con.getContentLength(); - if (contentLength != -1) { - response = new byte[contentLength]; - } else { - response = new byte[2048]; - contentLength = Integer.MAX_VALUE; - } - - while (total < contentLength) { - int count = in.read(response, total, response.length - total); - if (count < 0) - break; - - total += count; - if (total >= response.length && total < contentLength) { - response = Arrays.copyOf(response, total * 2); - } - } - response = Arrays.copyOf(response, total); + byte[] response = IOUtils.readFully(in, contentLength, false); OCSPResponse ocspResponse = new OCSPResponse(response, pkixParams, responderCert); diff --git a/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java b/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java index bb735141159..04c0b67ee82 100644 --- a/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java +++ b/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java @@ -34,6 +34,7 @@ import java.util.Iterator; import java.util.Set; import java.util.Arrays; +import sun.misc.IOUtils; import sun.security.pkcs.*; /** @@ -142,25 +143,7 @@ public class HttpTimestamper implements Timestamper { int total = 0; int contentLength = connection.getContentLength(); - if (contentLength != -1) { - replyBuffer = new byte[contentLength]; - } else { - replyBuffer = new byte[2048]; - contentLength = Integer.MAX_VALUE; - } - - while (total < contentLength) { - int count = input.read(replyBuffer, total, - replyBuffer.length - total); - if (count < 0) - break; - - total += count; - if (total >= replyBuffer.length && total < contentLength) { - replyBuffer = Arrays.copyOf(replyBuffer, total * 2); - } - } - replyBuffer = Arrays.copyOf(replyBuffer, total); + replyBuffer = IOUtils.readFully(input, contentLength, false); if (DEBUG) { System.out.println("received timestamp response (length=" + diff --git a/jdk/src/share/classes/sun/security/util/DerValue.java b/jdk/src/share/classes/sun/security/util/DerValue.java index 114788beb26..c0f920d5e33 100644 --- a/jdk/src/share/classes/sun/security/util/DerValue.java +++ b/jdk/src/share/classes/sun/security/util/DerValue.java @@ -28,6 +28,7 @@ package sun.security.util; import java.io.*; import java.math.BigInteger; import java.util.Date; +import sun.misc.IOUtils; /** * Represents a single DER-encoded value. DER encoding rules are a subset @@ -382,12 +383,8 @@ public class DerValue { if (fullyBuffered && in.available() != length) throw new IOException("extra data given to DerValue constructor"); - byte[] bytes = new byte[length]; + byte[] bytes = IOUtils.readFully(in, length, true); - // n.b. readFully not needed in normal fullyBuffered case - DataInputStream dis = new DataInputStream(in); - - dis.readFully(bytes); buffer = new DerInputBuffer(bytes); return new DerInputStream(buffer); } diff --git a/jdk/test/sun/security/util/DerValue/BadValue.java b/jdk/test/sun/security/util/DerValue/BadValue.java new file mode 100644 index 00000000000..cbe2c6ab45f --- /dev/null +++ b/jdk/test/sun/security/util/DerValue/BadValue.java @@ -0,0 +1,119 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6864911 + * @summary ASN.1/DER input stream parser needs more work + */ + +import java.io.*; +import sun.security.util.*; +import sun.misc.IOUtils; + +public class BadValue { + + public static void main(String[] args) throws Exception { + + // Test IOUtils.readFully + + // We have 4 bytes + InputStream in = new ByteArrayInputStream(new byte[10]); + byte[] bs = IOUtils.readFully(in, 4, true); + if (bs.length != 4 || in.available() != 6) { + throw new Exception("First read error"); + } + // But only 6 left + bs = IOUtils.readFully(in, 10, false); + if (bs.length != 6 || in.available() != 0) { + throw new Exception("Second read error"); + } + // MAX read as much as it can + in = new ByteArrayInputStream(new byte[10]); + bs = IOUtils.readFully(in, Integer.MAX_VALUE, true); + if (bs.length != 10 || in.available() != 0) { + throw new Exception("Second read error"); + } + // MAX ignore readAll + in = new ByteArrayInputStream(new byte[10]); + bs = IOUtils.readFully(in, Integer.MAX_VALUE, false); + if (bs.length != 10 || in.available() != 0) { + throw new Exception("Second read error"); + } + // 20>10, readAll means failure + in = new ByteArrayInputStream(new byte[10]); + try { + bs = IOUtils.readFully(in, 20, true); + throw new Exception("Third read error"); + } catch (EOFException e) { + // OK + } + int bignum = 10 * 1024 * 1024; + bs = IOUtils.readFully(new SuperSlowStream(bignum), -1, true); + if (bs.length != bignum) { + throw new Exception("Fourth read error"); + } + + // Test DerValue + byte[] input = {0x04, (byte)0x84, 0x40, 0x00, 0x42, 0x46, 0x4b}; + try { + new DerValue(new ByteArrayInputStream(input)); + } catch (IOException ioe) { + // This is OK + } + } +} + +/** + * An InputStream contains a given number of bytes, but only returns one byte + * per read. + */ +class SuperSlowStream extends InputStream { + private int p; + /** + * @param Initial capacity + */ + public SuperSlowStream(int capacity) { + p = capacity; + } + @Override + public int read() throws IOException { + if (p > 0) { + p--; + return 0; + } else { + return -1; + } + } + @Override + public int read(byte b[], int off, int len) throws IOException { + if (len == 0) return 0; + if (p > 0) { + p--; + b[off] = 0; + return 1; + } else { + return -1; + } + } +} From c14324faa56dae86e7732827ab626495b6b48bde Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Tue, 18 Aug 2009 20:47:13 -0700 Subject: [PATCH 002/172] 6861062: Disable MD2 support Reviewed-by: mullan, weijun --- .../provider/certpath/AlgorithmChecker.java | 119 ++++ .../certpath/DistributionPointFetcher.java | 10 + .../provider/certpath/ForwardBuilder.java | 5 + .../provider/certpath/OCSPChecker.java | 27 +- .../provider/certpath/OCSPResponse.java | 11 + .../certpath/PKIXCertPathValidator.java | 4 +- .../provider/certpath/ReverseBuilder.java | 5 +- .../security/validator/SimpleValidator.java | 9 + .../validator/ValidatorException.java | 5 +- .../DisabledAlgorithms/CPBuilder.java | 442 ++++++++++++ .../CPValidatorEndEntity.java | 363 ++++++++++ .../CPValidatorIntermediate.java | 256 +++++++ .../CPValidatorTrustAnchor.java | 169 +++++ .../certpath/DisabledAlgorithms/README | 640 ++++++++++++++++++ .../certpath/DisabledAlgorithms/generate.sh | 255 +++++++ .../certpath/DisabledAlgorithms/openssl.cnf | 206 ++++++ 16 files changed, 2518 insertions(+), 8 deletions(-) create mode 100644 jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java create mode 100644 jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPBuilder.java create mode 100644 jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorEndEntity.java create mode 100644 jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorIntermediate.java create mode 100644 jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorTrustAnchor.java create mode 100644 jdk/test/sun/security/provider/certpath/DisabledAlgorithms/README create mode 100644 jdk/test/sun/security/provider/certpath/DisabledAlgorithms/generate.sh create mode 100644 jdk/test/sun/security/provider/certpath/DisabledAlgorithms/openssl.cnf diff --git a/jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java new file mode 100644 index 00000000000..0921351863e --- /dev/null +++ b/jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java @@ -0,0 +1,119 @@ +/* + * Copyright 2009 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.security.provider.certpath; + +import java.util.Set; +import java.util.Collection; +import java.util.Locale; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.security.cert.X509CRL; +import java.security.cert.CertPathValidatorException; +import java.security.cert.PKIXCertPathChecker; + +import sun.security.x509.AlgorithmId; + +/** + * AlgorithmChecker is a PKIXCertPathChecker that checks that + * the signature algorithm of the specified certificate is not disabled. + * + * @author Xuelei Fan + */ +final public class AlgorithmChecker extends PKIXCertPathChecker { + + // the disabled algorithms + private static final String[] disabledAlgorithms = new String[] {"md2"}; + + // singleton instance + static final AlgorithmChecker INSTANCE = new AlgorithmChecker(); + + /** + * Default Constructor + */ + private AlgorithmChecker() { + // do nothing + } + + /** + * Return a AlgorithmChecker instance. + */ + static AlgorithmChecker getInstance() { + return INSTANCE; + } + + /** + * Initializes the internal state of the checker from parameters + * specified in the constructor. + */ + public void init(boolean forward) throws CertPathValidatorException { + // do nothing + } + + public boolean isForwardCheckingSupported() { + return false; + } + + public Set getSupportedExtensions() { + return null; + } + + /** + * Checks the signature algorithm of the specified certificate. + */ + public void check(Certificate cert, Collection unresolvedCritExts) + throws CertPathValidatorException { + check(cert); + } + + public static void check(Certificate cert) + throws CertPathValidatorException { + X509Certificate xcert = (X509Certificate)cert; + check(xcert.getSigAlgName()); + } + + static void check(AlgorithmId aid) throws CertPathValidatorException { + check(aid.getName()); + } + + static void check(X509CRL crl) throws CertPathValidatorException { + check(crl.getSigAlgName()); + } + + private static void check(String algName) + throws CertPathValidatorException { + + String lowerCaseAlgName = algName.toLowerCase(Locale.ENGLISH); + + for (String disabled : disabledAlgorithms) { + // checking the signature algorithm name + if (lowerCaseAlgName.indexOf(disabled) != -1) { + throw new CertPathValidatorException( + "algorithm check failed: " + algName + " is disabled"); + } + } + } + +} diff --git a/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java b/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java index 39ee1f1dad6..8d94adb32cc 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java @@ -309,6 +309,16 @@ class DistributionPointFetcher { X500Name certIssuer = (X500Name) certImpl.getIssuerDN(); X500Name crlIssuer = (X500Name) crlImpl.getIssuerDN(); + // check the crl signature algorithm + try { + AlgorithmChecker.check(crl); + } catch (CertPathValidatorException cpve) { + if (debug != null) { + debug.println("CRL signature algorithm check failed: " + cpve); + } + return false; + } + // if crlIssuer is set, verify that it matches the issuer of the // CRL and the CRL contains an IDP extension with the indirectCRL // boolean asserted. Otherwise, verify that the CRL issuer matches the diff --git a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java index 393a7663c91..59b95dc9d1d 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java @@ -715,6 +715,11 @@ class ForwardBuilder extends Builder { /* we don't perform any validation of the trusted cert */ if (!isTrustedCert) { + /* + * check that the signature algorithm is not disabled. + */ + AlgorithmChecker.check(cert); + /* * Check CRITICAL private extensions for user checkers that * support forward checking (forwardCheckers) and remove diff --git a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java index b9d246c20b0..39c25025738 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java @@ -297,12 +297,29 @@ class OCSPChecker extends PKIXCertPathChecker { } if (filter != null) { List certStores = pkixParams.getCertStores(); + AlgorithmChecker algChecker= + AlgorithmChecker.getInstance(); for (CertStore certStore : certStores) { - Iterator i = - certStore.getCertificates(filter).iterator(); - if (i.hasNext()) { - responderCert = (X509Certificate) i.next(); - seekResponderCert = false; // done + for (Certificate selected : + certStore.getCertificates(filter)) { + try { + // don't bother to trust algorithm disabled + // certificate as responder + algChecker.check(selected); + + responderCert = (X509Certificate)selected; + seekResponderCert = false; // done + break; + } catch (CertPathValidatorException cpve) { + if (DEBUG != null) { + DEBUG.println( + "OCSP responder certificate " + + "algorithm check failed: " + cpve); + } + } + } + + if (!seekResponderCert) { break; } } diff --git a/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java b/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java index cdadc45f66c..f7c5dbc5cad 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java @@ -230,6 +230,11 @@ class OCSPResponse { new DerInputStream(derIn.getOctetString()); DerValue[] seqTmp = basicOCSPResponse.getSequence(2); + + if (seqTmp.length < 3) { + throw new IOException("Unexpected BasicOCSPResponse value"); + } + DerValue responseData = seqTmp[0]; // Need the DER encoded ResponseData to verify the signature later @@ -312,6 +317,9 @@ class OCSPResponse { // signatureAlgorithmId sigAlgId = AlgorithmId.parse(seqTmp[1]); + // check that the signature algorithm is not disabled. + AlgorithmChecker.check(sigAlgId); + // signature byte[] signature = seqTmp[2].getBitString(); X509CertImpl[] x509Certs = null; @@ -345,6 +353,9 @@ class OCSPResponse { } else if (cert.getIssuerX500Principal().equals( responderCert.getSubjectX500Principal())) { + // check the certificate algorithm + AlgorithmChecker.check(cert); + // Check for the OCSPSigning key purpose List keyPurposes = cert.getExtendedKeyUsage(); if (keyPurposes == null || diff --git a/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java b/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java index 63335d2342c..3511ad7de54 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, 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 @@ -276,6 +276,7 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { int certPathLen = certList.size(); basicChecker = new BasicChecker(anchor, testDate, sigProvider, false); + AlgorithmChecker algorithmChecker= AlgorithmChecker.getInstance(); KeyChecker keyChecker = new KeyChecker(certPathLen, pkixParam.getTargetCertConstraints()); ConstraintsChecker constraintsChecker = @@ -292,6 +293,7 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { ArrayList certPathCheckers = new ArrayList(); // add standard checkers that we will be using + certPathCheckers.add(algorithmChecker); certPathCheckers.add(keyChecker); certPathCheckers.add(constraintsChecker); certPathCheckers.add(policyChecker); diff --git a/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java b/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java index 6f826026caf..c8762ef7447 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, 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 @@ -347,6 +347,9 @@ class ReverseBuilder extends Builder { return; } + /* check that the signature algorithm is not disabled. */ + AlgorithmChecker.check(cert); + /* * check for looping - abort a loop if * ((we encounter the same certificate twice) AND diff --git a/jdk/src/share/classes/sun/security/validator/SimpleValidator.java b/jdk/src/share/classes/sun/security/validator/SimpleValidator.java index d21466a608b..eff9045c2f6 100644 --- a/jdk/src/share/classes/sun/security/validator/SimpleValidator.java +++ b/jdk/src/share/classes/sun/security/validator/SimpleValidator.java @@ -40,6 +40,8 @@ import sun.security.util.DerInputStream; import sun.security.util.DerOutputStream; import sun.security.util.ObjectIdentifier; +import sun.security.provider.certpath.AlgorithmChecker; + /** * A simple validator implementation. It is based on code from the JSSE * X509TrustManagerImpl. This implementation is designed for compatibility with @@ -134,6 +136,13 @@ public final class SimpleValidator extends Validator { X509Certificate issuerCert = chain[i + 1]; X509Certificate cert = chain[i]; + // check certificate algorithm + try { + AlgorithmChecker.check(cert); + } catch (CertPathValidatorException cpve) { + throw new ValidatorException + (ValidatorException.T_ALGORITHM_DISABLED, cert, cpve); + } // no validity check for code signing certs if ((variant.equals(VAR_CODE_SIGNING) == false) diff --git a/jdk/src/share/classes/sun/security/validator/ValidatorException.java b/jdk/src/share/classes/sun/security/validator/ValidatorException.java index 67f42cfa472..53b8667f29f 100644 --- a/jdk/src/share/classes/sun/security/validator/ValidatorException.java +++ b/jdk/src/share/classes/sun/security/validator/ValidatorException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2009 Sun Microsystems, 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 @@ -55,6 +55,9 @@ public class ValidatorException extends CertificateException { public final static Object T_NAME_CHAINING = "Certificate chaining error"; + public final static Object T_ALGORITHM_DISABLED = + "Certificate signature algorithm disabled"; + private Object type; private X509Certificate cert; diff --git a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPBuilder.java b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPBuilder.java new file mode 100644 index 00000000000..891967fd7e7 --- /dev/null +++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPBuilder.java @@ -0,0 +1,442 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * + * @bug 6861062 + * @summary Disable MD2 support + * + * @run main/othervm CPBuilder trustAnchor_SHA1withRSA_1024 0 true + * @run main/othervm CPBuilder trustAnchor_SHA1withRSA_512 0 true + * @run main/othervm CPBuilder intermediate_SHA1withRSA_1024_1024 1 true + * @run main/othervm CPBuilder intermediate_SHA1withRSA_1024_512 1 true + * @run main/othervm CPBuilder intermediate_SHA1withRSA_512_1024 1 true + * @run main/othervm CPBuilder intermediate_SHA1withRSA_512_512 1 true + * @run main/othervm CPBuilder intermediate_MD2withRSA_1024_1024 1 false + * @run main/othervm CPBuilder intermediate_MD2withRSA_1024_512 1 false + * @run main/othervm CPBuilder endentiry_SHA1withRSA_1024_1024 2 true + * @run main/othervm CPBuilder endentiry_SHA1withRSA_1024_512 2 true + * @run main/othervm CPBuilder endentiry_SHA1withRSA_512_1024 2 true + * @run main/othervm CPBuilder endentiry_SHA1withRSA_512_512 2 true + * @run main/othervm CPBuilder endentiry_MD2withRSA_1024_1024 2 false + * @run main/othervm CPBuilder endentiry_MD2withRSA_1024_512 2 false + * + * @author Xuelei Fan + */ + +import java.io.*; +import java.net.SocketException; +import java.util.*; +import java.security.Security; +import java.security.cert.*; +import sun.security.util.DerInputStream; + +public class CPBuilder { + + // SHA1withRSA 1024 + static String trustAnchor_SHA1withRSA_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDRaFw0zMDA3MTcwMTExNDRa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB\n" + + "AQUAA4GNADCBiQKBgQC8UdC863pFk1Rvd7xUYd60+e9KsLhb6SqOfU42ZA715FcH\n" + + "E1TRvQPmYzAnHcO04TrWZQtO6E+E2RCmeBnetBvIMVka688QkO14wnrIrf2tRodd\n" + + "rZNZEBzkX+zyXCRo9tKEUDFf9Qze7Ilbb+Zzm9CUfu4M1Oz6iQcXRx7aM0jEAQID\n" + + "AQABo4GJMIGGMB0GA1UdDgQWBBTn0C+xmZY/BTab4W9gBp3dGa7WgjBHBgNVHSME\n" + + "QDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEwHzELMAkGA1UEBhMCVVMxEDAO\n" + + "BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAgQw\n" + + "DQYJKoZIhvcNAQEFBQADgYEAiCXL2Yp4ruyRXAIJ8zBEaPC9oV2agqgbSbly2z8z\n" + + "Ik5SeSRysP+GHBpb8uNyANJnQKv+T0GrJiTLMBjKCOiJl6xzk3EZ2wbQB6G/SQ9+\n" + + "UWcsXSC8oGSEPpkj5In/9/UbuUIfT9H8jmdyLNKQvlqgq6kyfnskME7ptGgT95Hc\n" + + "tas=\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 + static String trustAnchor_SHA1withRSA_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIBuTCCAWOgAwIBAgIBADANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDRaFw0zMDA3MTcwMTExNDRa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMFwwDQYJKoZIhvcNAQEB\n" + + "BQADSwAwSAJBAM0Kn4ieCdCHsrm78ZMMN4jQEEEqACAMKB7O8j9g4gfz2oAfmHwv\n" + + "7JH/hZ0Xen1zUmBbwe+e2J5D/4Fisp9Bn98CAwEAAaOBiTCBhjAdBgNVHQ4EFgQU\n" + + "g4Kwd47hdNQBp8grZsRJ5XvhvxAwRwYDVR0jBEAwPoAUg4Kwd47hdNQBp8grZsRJ\n" + + "5XvhvxChI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlggEAMA8G\n" + + "A1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0GCSqGSIb3DQEBBQUAA0EAn77b\n" + + "FJx+HvyRvjZYCzMjnUct3Ql4iLOkURYDh93J5TXi/l9ajvAMEuwzYj0qZ+Ktm/ia\n" + + "U5r+8B9nzx+j2Zh3kw==\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 1024 signed with RSA 1024 + static String intermediate_SHA1withRSA_1024_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICUDCCAbmgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDhaFw0yOTA0MjMwMTExNDha\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQEFBQADgYEAHze3wAcIe84zNOoN\n" + + "P8l9EmlVVoU30z3LB3hxq3m/dC/4gE5Z9Z8EG1wJw4qaxlTZ4dif12nbTTdofVhb\n" + + "Bd4syjo6fcUA4q7sfg9TFpoHQ+Ap7PgjK99moMKdMy50Xy8s6FPvaVkF89s66Z6y\n" + + "e4q7TSwe6QevGOZaL5N/iy2XGEs=\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 1024 signed with RSA 512 + static String intermediate_SHA1withRSA_1024_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICDzCCAbmgAwIBAgIBAzANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBSDgrB3juF01AGnyCtmxEnle+G/EKEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQEFBQADQQCYNmdkONfuk07XjRze\n" + + "WQyq2cfdae4uIdyUfa2rpgYMtSXuQW3/XrQGiz4G6WBXA2wo7folOOpAKYgvHPrm\n" + + "w6Dd\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 signed with RSA 1024 + static String intermediate_SHA1withRSA_512_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICDDCCAXWgAwIBAgIBBDANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKubXYoEHZpZkhzA9XX+NrpqJ4SV\n" + + "lOMBoL3aWExQpJIgrUaZfbGMBBozIHBJMMayokguHbJvq4QigEgLuhfJNqsCAwEA\n" + + "AaOBiTCBhjAdBgNVHQ4EFgQUN0CHiTYPtjyvpP2a6y6mhsZ6U40wRwYDVR0jBEAw\n" + + "PoAU59AvsZmWPwU2m+FvYAad3Rmu1oKhI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD\n" + + "VQQKEwdFeGFtcGxlggEAMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0G\n" + + "CSqGSIb3DQEBBQUAA4GBAE2VOlw5ySLT3gUzKCYEga4QPaSrf6lHHPi2g48LscEY\n" + + "h9qQXh4nuIVugReBIEf6N49RdT+M2cgRJo4sZ3ukYLGQzxNuttL5nPSuuvrAR1oG\n" + + "LUyzOWcUpKHbVHi6zlTt79RvTKZvLcduLutmtPtLJcM9PdiAI1wEooSgxTwZtB/Z\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 signed with RSA 512 + static String intermediate_SHA1withRSA_512_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIByzCCAXWgAwIBAgIBBTANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKubXYoEHZpZkhzA9XX+NrpqJ4SV\n" + + "lOMBoL3aWExQpJIgrUaZfbGMBBozIHBJMMayokguHbJvq4QigEgLuhfJNqsCAwEA\n" + + "AaOBiTCBhjAdBgNVHQ4EFgQUN0CHiTYPtjyvpP2a6y6mhsZ6U40wRwYDVR0jBEAw\n" + + "PoAUg4Kwd47hdNQBp8grZsRJ5XvhvxChI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD\n" + + "VQQKEwdFeGFtcGxlggEAMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0G\n" + + "CSqGSIb3DQEBBQUAA0EAoCf0Zu559qcB4xPpzqkVsYiyW49S4Yc0mmQXb1yoQgLx\n" + + "O+DCkjG5d14+t1MsnkhB2izoQUMxQ3vDc1YnA/tEpw==\n" + + "-----END CERTIFICATE-----"; + + // MD2withRSA 1024 signed with RSA 1024 + static String intermediate_MD2withRSA_1024_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICUDCCAbmgAwIBAgIBBjANBgkqhkiG9w0BAQIFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQECBQADgYEAPtEjwbWuC5kc4DPc\n" + + "Ttf/wdbD8ZCdAWzcc3XF9q1TlvwVMNk6mbfM05y6ZVsztKTkwZ4EcvFu/yIqw1EB\n" + + "E1zlXQCaWXT3/ZMbqYZV4+mx+RUl8spUCb1tda25jnTg3mTOzB1iztm4gy903EMd\n" + + "m8omKDKeCgcw5dR4ITQYvyxe1as=\n" + + "-----END CERTIFICATE-----"; + + // MD2withRSA 1024 signed with RSA 512 + static String intermediate_MD2withRSA_1024_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICDzCCAbmgAwIBAgIBBzANBgkqhkiG9w0BAQIFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBSDgrB3juF01AGnyCtmxEnle+G/EKEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQECBQADQQBHok1v6xymtpB7N9xy\n" + + "0OmDT27uhmzlP0eOzJvXVxj3Oi9TLQJgCUJ9122MzfRAs1E1uJTtvuu+UmI80NQx\n" + + "KQdp\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 1024 signed with RSA 1024 + static String endentiry_SHA1withRSA_1024_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICNzCCAaCgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTBaFw0yOTA0MjMwMTExNTBaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG\n" + + "9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt\n" + + "vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v\n" + + "z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6\n" + + "c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07\n" + + "OorBleV92TAfBgNVHSMEGDAWgBTfWD9mRTppcUAlUqGuu/R5t8CB5jANBgkqhkiG\n" + + "9w0BAQUFAAOBgQAOfIeasDg91CR3jGfuAEVKwncM1OPFmniAUcdPm74cCAyJ90Me\n" + + "dhUElWPGoAuXGfiyZlOlGUYWqEroe/dnkmnotJjLWR+MA4ZyX3O1YI8T4W3deWcC\n" + + "J4WMCF7mp17SaYYKX9F0AxwNJFpUkbB41IkTxPr0MmzB1871/pbY8dLAvA==\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 1024 signed with RSA 512 + static String endentiry_SHA1withRSA_1024_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB9jCCAaCgAwIBAgIBAzANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTBaFw0yOTA0MjMwMTExNTBaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG\n" + + "9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt\n" + + "vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v\n" + + "z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6\n" + + "c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07\n" + + "OorBleV92TAfBgNVHSMEGDAWgBQ3QIeJNg+2PK+k/ZrrLqaGxnpTjTANBgkqhkiG\n" + + "9w0BAQUFAANBADV6X+ea0ftEKXy7yKNAbdIp35893T6AVwbdclomPkeOs86OtoTG\n" + + "1BIzWSK9QE7W6Wbf63e2RdcqoLK+DxsuwUg=\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 signed with RSA 1024 + static String endentiry_SHA1withRSA_512_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB8zCCAVygAwIBAgIBBDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTBcMA0GCSqGSIb3\n" + + "DQEBAQUAA0sAMEgCQQCpfQzhld7w2JhW/aRaLkmrLrc/QAsQE+J4DXioXaajsWPo\n" + + "uMmYmuiQolb6OIY/LcivSubKM3G5PkAWoovUPIWLAgMBAAGjTzBNMAsGA1UdDwQE\n" + + "AwID6DAdBgNVHQ4EFgQUFWuXLkf4Ji57H9ISycgWi982TUIwHwYDVR0jBBgwFoAU\n" + + "31g/ZkU6aXFAJVKhrrv0ebfAgeYwDQYJKoZIhvcNAQEFBQADgYEAUyW8PrEdbzLu\n" + + "B+h6UemBOJ024rYq90hJE/5wUEKPvxZ9vPEUgl+io6cGhL3cLfxfh6z5xtEGp4Tb\n" + + "NB0Ye3Qi01FBiNDY8s3rQRrmel6VysU8u+0Oi2jmQY6vZXn/zXN5rrTLITCaSicG\n" + + "dOMv1xLM83Ee432WWlDwKOUxhzDGpWc=\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 signed with RSA 512 + static String endentiry_SHA1withRSA_512_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIBsjCCAVygAwIBAgIBBTANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTBcMA0GCSqGSIb3\n" + + "DQEBAQUAA0sAMEgCQQCpfQzhld7w2JhW/aRaLkmrLrc/QAsQE+J4DXioXaajsWPo\n" + + "uMmYmuiQolb6OIY/LcivSubKM3G5PkAWoovUPIWLAgMBAAGjTzBNMAsGA1UdDwQE\n" + + "AwID6DAdBgNVHQ4EFgQUFWuXLkf4Ji57H9ISycgWi982TUIwHwYDVR0jBBgwFoAU\n" + + "N0CHiTYPtjyvpP2a6y6mhsZ6U40wDQYJKoZIhvcNAQEFBQADQQBG4grtrVEHick0\n" + + "z/6Lcl/MGyHT0c8KTXE0AMVXG1NRjAicAmYno/yDaJ9OmfymObKZKV9fF7yCW/N/\n" + + "TMU6m7N0\n" + + "-----END CERTIFICATE-----"; + + // MD2withRSA 1024 signed with RSA 1024 + static String endentiry_MD2withRSA_1024_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICNzCCAaCgAwIBAgIBBjANBgkqhkiG9w0BAQIFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG\n" + + "9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt\n" + + "vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v\n" + + "z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6\n" + + "c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07\n" + + "OorBleV92TAfBgNVHSMEGDAWgBTfWD9mRTppcUAlUqGuu/R5t8CB5jANBgkqhkiG\n" + + "9w0BAQIFAAOBgQBxKsFf8NNQcXjDoKJJSG4Rk6ikcrhiGYuUI32+XHvs6hnav1Zc\n" + + "aJUpy7J4gMj/MnysMh/4AF9+m6zEEjuisXKUbYZhgtJxz+ukGSo163mJ8QJiAlRb\n" + + "Iwsy81r08mlSCR6jx2YhDAUxJIPC92R5Vb4CEutB7tWTwwz7vIHq330erA==\n" + + "-----END CERTIFICATE-----"; + + // MD2withRSA 1024 signed with RSA 512 + static String endentiry_MD2withRSA_1024_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB9jCCAaCgAwIBAgIBBzANBgkqhkiG9w0BAQIFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG\n" + + "9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt\n" + + "vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v\n" + + "z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6\n" + + "c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07\n" + + "OorBleV92TAfBgNVHSMEGDAWgBQ3QIeJNg+2PK+k/ZrrLqaGxnpTjTANBgkqhkiG\n" + + "9w0BAQIFAANBAIX63Ypi9P71RnC/pcMbhD+wekRFsTzU593X3MC7tyBJtEXwvAZG\n" + + "iMxXF5A+ohlr7/CrkV7ZTL8PLxnJdY5Y8rQ=\n" + + "-----END CERTIFICATE-----"; + + static HashMap certmap = new HashMap(); + static { + certmap.put("trustAnchor_SHA1withRSA_1024", + trustAnchor_SHA1withRSA_1024); + certmap.put("trustAnchor_SHA1withRSA_512", + trustAnchor_SHA1withRSA_512); + certmap.put("intermediate_SHA1withRSA_1024_1024", + intermediate_SHA1withRSA_1024_1024); + certmap.put("intermediate_SHA1withRSA_1024_512", + intermediate_SHA1withRSA_1024_512); + certmap.put("intermediate_SHA1withRSA_512_1024", + intermediate_SHA1withRSA_512_1024); + certmap.put("intermediate_SHA1withRSA_512_512", + intermediate_SHA1withRSA_512_512); + certmap.put("intermediate_MD2withRSA_1024_1024", + intermediate_MD2withRSA_1024_1024); + certmap.put("intermediate_MD2withRSA_1024_512", + intermediate_MD2withRSA_1024_512); + certmap.put("endentiry_SHA1withRSA_1024_1024", + endentiry_SHA1withRSA_1024_1024); + certmap.put("endentiry_SHA1withRSA_1024_512", + endentiry_SHA1withRSA_1024_512); + certmap.put("endentiry_SHA1withRSA_512_1024", + endentiry_SHA1withRSA_512_1024); + certmap.put("endentiry_SHA1withRSA_512_512", + endentiry_SHA1withRSA_512_512); + certmap.put("endentiry_MD2withRSA_1024_1024", + endentiry_MD2withRSA_1024_1024); + certmap.put("endentiry_MD2withRSA_1024_512", + endentiry_MD2withRSA_1024_512); + } + + private static Set generateTrustAnchors() + throws CertificateException { + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + HashSet anchors = new HashSet(); + + ByteArrayInputStream is = + new ByteArrayInputStream(trustAnchor_SHA1withRSA_1024.getBytes()); + Certificate cert = cf.generateCertificate(is); + TrustAnchor anchor = new TrustAnchor((X509Certificate)cert, null); + anchors.add(anchor); + + is = new ByteArrayInputStream(trustAnchor_SHA1withRSA_512.getBytes()); + cert = cf.generateCertificate(is); + anchor = new TrustAnchor((X509Certificate)cert, null); + anchors.add(anchor); + + return anchors; + } + + private static CertStore generateCertificateStore() throws Exception { + Collection entries = new HashSet(); + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + for (String key : certmap.keySet()) { + String certStr = certmap.get(key); + ByteArrayInputStream is = + new ByteArrayInputStream(certStr.getBytes());; + Certificate cert = cf.generateCertificate(is); + entries.add(cert); + } + + return CertStore.getInstance("Collection", + new CollectionCertStoreParameters(entries)); + } + + private static X509CertSelector generateSelector(String name) + throws Exception { + X509CertSelector selector = new X509CertSelector(); + + String certStr = certmap.get(name); + if (certStr == null) { + return null; + } + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + ByteArrayInputStream is = new ByteArrayInputStream(certStr.getBytes()); + X509Certificate target = (X509Certificate)cf.generateCertificate(is); + + selector.setCertificate(target); + + return selector; + } + + private static boolean match(String name, Certificate cert) + throws Exception { + X509CertSelector selector = new X509CertSelector(); + + String certStr = certmap.get(name); + if (certStr == null) { + return false; + } + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + ByteArrayInputStream is = new ByteArrayInputStream(certStr.getBytes()); + X509Certificate target = (X509Certificate)cf.generateCertificate(is); + + return target.equals(cert); + } + + public static void main(String args[]) throws Exception { + + CertPathBuilder builder = CertPathBuilder.getInstance("PKIX"); + + X509CertSelector selector = generateSelector(args[0]); + if (selector == null) { + // no target certificate, ignore it + return; + } + + Set anchors = generateTrustAnchors(); + CertStore certs = generateCertificateStore(); + + PKIXBuilderParameters params = + new PKIXBuilderParameters(anchors, selector); + params.addCertStore(certs); + params.setRevocationEnabled(false); + params.setDate(new Date(109, 9, 1)); // 2009-09-01 + + boolean success = Boolean.valueOf(args[2]); + try { + PKIXCertPathBuilderResult result = + (PKIXCertPathBuilderResult)builder.build(params); + if (!success) { + throw new Exception("expected algorithm disabled exception"); + } + + int length = Integer.parseInt(args[1]); + List path = + result.getCertPath().getCertificates(); + if (length != path.size()) { + throw new Exception("unexpected certification path length"); + } + + if (!path.isEmpty()) { // the target is not a trust anchor + if (!match(args[0], path.get(0))) { + throw new Exception("unexpected certificate"); + } + } + } catch (CertPathBuilderException cpbe) { + if (success) { + throw new Exception("unexpected exception"); + } else { + System.out.println("Get the expected exception " + cpbe); + } + } + } + +} diff --git a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorEndEntity.java b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorEndEntity.java new file mode 100644 index 00000000000..bb0e886133e --- /dev/null +++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorEndEntity.java @@ -0,0 +1,363 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * + * @bug 6861062 + * @summary Disable MD2 support + * + * @author Xuelei Fan + */ + +import java.io.*; +import java.net.SocketException; +import java.util.*; +import java.security.Security; +import java.security.cert.*; + +public class CPValidatorEndEntity { + + // SHA1withRSA 1024 + static String trustAnchor_SHA1withRSA_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDRaFw0zMDA3MTcwMTExNDRa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB\n" + + "AQUAA4GNADCBiQKBgQC8UdC863pFk1Rvd7xUYd60+e9KsLhb6SqOfU42ZA715FcH\n" + + "E1TRvQPmYzAnHcO04TrWZQtO6E+E2RCmeBnetBvIMVka688QkO14wnrIrf2tRodd\n" + + "rZNZEBzkX+zyXCRo9tKEUDFf9Qze7Ilbb+Zzm9CUfu4M1Oz6iQcXRx7aM0jEAQID\n" + + "AQABo4GJMIGGMB0GA1UdDgQWBBTn0C+xmZY/BTab4W9gBp3dGa7WgjBHBgNVHSME\n" + + "QDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEwHzELMAkGA1UEBhMCVVMxEDAO\n" + + "BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAgQw\n" + + "DQYJKoZIhvcNAQEFBQADgYEAiCXL2Yp4ruyRXAIJ8zBEaPC9oV2agqgbSbly2z8z\n" + + "Ik5SeSRysP+GHBpb8uNyANJnQKv+T0GrJiTLMBjKCOiJl6xzk3EZ2wbQB6G/SQ9+\n" + + "UWcsXSC8oGSEPpkj5In/9/UbuUIfT9H8jmdyLNKQvlqgq6kyfnskME7ptGgT95Hc\n" + + "tas=\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 + static String trustAnchor_SHA1withRSA_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIBuTCCAWOgAwIBAgIBADANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDRaFw0zMDA3MTcwMTExNDRa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMFwwDQYJKoZIhvcNAQEB\n" + + "BQADSwAwSAJBAM0Kn4ieCdCHsrm78ZMMN4jQEEEqACAMKB7O8j9g4gfz2oAfmHwv\n" + + "7JH/hZ0Xen1zUmBbwe+e2J5D/4Fisp9Bn98CAwEAAaOBiTCBhjAdBgNVHQ4EFgQU\n" + + "g4Kwd47hdNQBp8grZsRJ5XvhvxAwRwYDVR0jBEAwPoAUg4Kwd47hdNQBp8grZsRJ\n" + + "5XvhvxChI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlggEAMA8G\n" + + "A1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0GCSqGSIb3DQEBBQUAA0EAn77b\n" + + "FJx+HvyRvjZYCzMjnUct3Ql4iLOkURYDh93J5TXi/l9ajvAMEuwzYj0qZ+Ktm/ia\n" + + "U5r+8B9nzx+j2Zh3kw==\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 1024 signed with RSA 1024 + static String intermediate_SHA1withRSA_1024_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICUDCCAbmgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDhaFw0yOTA0MjMwMTExNDha\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQEFBQADgYEAHze3wAcIe84zNOoN\n" + + "P8l9EmlVVoU30z3LB3hxq3m/dC/4gE5Z9Z8EG1wJw4qaxlTZ4dif12nbTTdofVhb\n" + + "Bd4syjo6fcUA4q7sfg9TFpoHQ+Ap7PgjK99moMKdMy50Xy8s6FPvaVkF89s66Z6y\n" + + "e4q7TSwe6QevGOZaL5N/iy2XGEs=\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 1024 signed with RSA 512 + static String intermediate_SHA1withRSA_1024_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICDzCCAbmgAwIBAgIBAzANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBSDgrB3juF01AGnyCtmxEnle+G/EKEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQEFBQADQQCYNmdkONfuk07XjRze\n" + + "WQyq2cfdae4uIdyUfa2rpgYMtSXuQW3/XrQGiz4G6WBXA2wo7folOOpAKYgvHPrm\n" + + "w6Dd\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 signed with RSA 1024 + static String intermediate_SHA1withRSA_512_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICDDCCAXWgAwIBAgIBBDANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKubXYoEHZpZkhzA9XX+NrpqJ4SV\n" + + "lOMBoL3aWExQpJIgrUaZfbGMBBozIHBJMMayokguHbJvq4QigEgLuhfJNqsCAwEA\n" + + "AaOBiTCBhjAdBgNVHQ4EFgQUN0CHiTYPtjyvpP2a6y6mhsZ6U40wRwYDVR0jBEAw\n" + + "PoAU59AvsZmWPwU2m+FvYAad3Rmu1oKhI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD\n" + + "VQQKEwdFeGFtcGxlggEAMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0G\n" + + "CSqGSIb3DQEBBQUAA4GBAE2VOlw5ySLT3gUzKCYEga4QPaSrf6lHHPi2g48LscEY\n" + + "h9qQXh4nuIVugReBIEf6N49RdT+M2cgRJo4sZ3ukYLGQzxNuttL5nPSuuvrAR1oG\n" + + "LUyzOWcUpKHbVHi6zlTt79RvTKZvLcduLutmtPtLJcM9PdiAI1wEooSgxTwZtB/Z\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 signed with RSA 512 + static String intermediate_SHA1withRSA_512_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIByzCCAXWgAwIBAgIBBTANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKubXYoEHZpZkhzA9XX+NrpqJ4SV\n" + + "lOMBoL3aWExQpJIgrUaZfbGMBBozIHBJMMayokguHbJvq4QigEgLuhfJNqsCAwEA\n" + + "AaOBiTCBhjAdBgNVHQ4EFgQUN0CHiTYPtjyvpP2a6y6mhsZ6U40wRwYDVR0jBEAw\n" + + "PoAUg4Kwd47hdNQBp8grZsRJ5XvhvxChI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD\n" + + "VQQKEwdFeGFtcGxlggEAMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0G\n" + + "CSqGSIb3DQEBBQUAA0EAoCf0Zu559qcB4xPpzqkVsYiyW49S4Yc0mmQXb1yoQgLx\n" + + "O+DCkjG5d14+t1MsnkhB2izoQUMxQ3vDc1YnA/tEpw==\n" + + "-----END CERTIFICATE-----"; + + // MD2withRSA 1024 signed with RSA 1024 + static String intermediate_MD2withRSA_1024_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICUDCCAbmgAwIBAgIBBjANBgkqhkiG9w0BAQIFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQECBQADgYEAPtEjwbWuC5kc4DPc\n" + + "Ttf/wdbD8ZCdAWzcc3XF9q1TlvwVMNk6mbfM05y6ZVsztKTkwZ4EcvFu/yIqw1EB\n" + + "E1zlXQCaWXT3/ZMbqYZV4+mx+RUl8spUCb1tda25jnTg3mTOzB1iztm4gy903EMd\n" + + "m8omKDKeCgcw5dR4ITQYvyxe1as=\n" + + "-----END CERTIFICATE-----"; + + // MD2withRSA 1024 signed with RSA 512 + static String intermediate_MD2withRSA_1024_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICDzCCAbmgAwIBAgIBBzANBgkqhkiG9w0BAQIFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBSDgrB3juF01AGnyCtmxEnle+G/EKEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQECBQADQQBHok1v6xymtpB7N9xy\n" + + "0OmDT27uhmzlP0eOzJvXVxj3Oi9TLQJgCUJ9122MzfRAs1E1uJTtvuu+UmI80NQx\n" + + "KQdp\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 1024 signed with RSA 1024 + static String endentiry_SHA1withRSA_1024_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICNzCCAaCgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTBaFw0yOTA0MjMwMTExNTBaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG\n" + + "9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt\n" + + "vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v\n" + + "z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6\n" + + "c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07\n" + + "OorBleV92TAfBgNVHSMEGDAWgBTfWD9mRTppcUAlUqGuu/R5t8CB5jANBgkqhkiG\n" + + "9w0BAQUFAAOBgQAOfIeasDg91CR3jGfuAEVKwncM1OPFmniAUcdPm74cCAyJ90Me\n" + + "dhUElWPGoAuXGfiyZlOlGUYWqEroe/dnkmnotJjLWR+MA4ZyX3O1YI8T4W3deWcC\n" + + "J4WMCF7mp17SaYYKX9F0AxwNJFpUkbB41IkTxPr0MmzB1871/pbY8dLAvA==\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 1024 signed with RSA 512 + static String endentiry_SHA1withRSA_1024_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB9jCCAaCgAwIBAgIBAzANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTBaFw0yOTA0MjMwMTExNTBaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG\n" + + "9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt\n" + + "vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v\n" + + "z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6\n" + + "c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07\n" + + "OorBleV92TAfBgNVHSMEGDAWgBQ3QIeJNg+2PK+k/ZrrLqaGxnpTjTANBgkqhkiG\n" + + "9w0BAQUFAANBADV6X+ea0ftEKXy7yKNAbdIp35893T6AVwbdclomPkeOs86OtoTG\n" + + "1BIzWSK9QE7W6Wbf63e2RdcqoLK+DxsuwUg=\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 signed with RSA 1024 + static String endentiry_SHA1withRSA_512_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB8zCCAVygAwIBAgIBBDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTBcMA0GCSqGSIb3\n" + + "DQEBAQUAA0sAMEgCQQCpfQzhld7w2JhW/aRaLkmrLrc/QAsQE+J4DXioXaajsWPo\n" + + "uMmYmuiQolb6OIY/LcivSubKM3G5PkAWoovUPIWLAgMBAAGjTzBNMAsGA1UdDwQE\n" + + "AwID6DAdBgNVHQ4EFgQUFWuXLkf4Ji57H9ISycgWi982TUIwHwYDVR0jBBgwFoAU\n" + + "31g/ZkU6aXFAJVKhrrv0ebfAgeYwDQYJKoZIhvcNAQEFBQADgYEAUyW8PrEdbzLu\n" + + "B+h6UemBOJ024rYq90hJE/5wUEKPvxZ9vPEUgl+io6cGhL3cLfxfh6z5xtEGp4Tb\n" + + "NB0Ye3Qi01FBiNDY8s3rQRrmel6VysU8u+0Oi2jmQY6vZXn/zXN5rrTLITCaSicG\n" + + "dOMv1xLM83Ee432WWlDwKOUxhzDGpWc=\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 signed with RSA 512 + static String endentiry_SHA1withRSA_512_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIBsjCCAVygAwIBAgIBBTANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTBcMA0GCSqGSIb3\n" + + "DQEBAQUAA0sAMEgCQQCpfQzhld7w2JhW/aRaLkmrLrc/QAsQE+J4DXioXaajsWPo\n" + + "uMmYmuiQolb6OIY/LcivSubKM3G5PkAWoovUPIWLAgMBAAGjTzBNMAsGA1UdDwQE\n" + + "AwID6DAdBgNVHQ4EFgQUFWuXLkf4Ji57H9ISycgWi982TUIwHwYDVR0jBBgwFoAU\n" + + "N0CHiTYPtjyvpP2a6y6mhsZ6U40wDQYJKoZIhvcNAQEFBQADQQBG4grtrVEHick0\n" + + "z/6Lcl/MGyHT0c8KTXE0AMVXG1NRjAicAmYno/yDaJ9OmfymObKZKV9fF7yCW/N/\n" + + "TMU6m7N0\n" + + "-----END CERTIFICATE-----"; + + // MD2withRSA 1024 signed with RSA 1024 + static String endentiry_MD2withRSA_1024_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICNzCCAaCgAwIBAgIBBjANBgkqhkiG9w0BAQIFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG\n" + + "9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt\n" + + "vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v\n" + + "z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6\n" + + "c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07\n" + + "OorBleV92TAfBgNVHSMEGDAWgBTfWD9mRTppcUAlUqGuu/R5t8CB5jANBgkqhkiG\n" + + "9w0BAQIFAAOBgQBxKsFf8NNQcXjDoKJJSG4Rk6ikcrhiGYuUI32+XHvs6hnav1Zc\n" + + "aJUpy7J4gMj/MnysMh/4AF9+m6zEEjuisXKUbYZhgtJxz+ukGSo163mJ8QJiAlRb\n" + + "Iwsy81r08mlSCR6jx2YhDAUxJIPC92R5Vb4CEutB7tWTwwz7vIHq330erA==\n" + + "-----END CERTIFICATE-----"; + + // MD2withRSA 1024 signed with RSA 512 + static String endentiry_MD2withRSA_1024_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB9jCCAaCgAwIBAgIBBzANBgkqhkiG9w0BAQIFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx\n" + + "NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG\n" + + "9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt\n" + + "vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v\n" + + "z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6\n" + + "c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07\n" + + "OorBleV92TAfBgNVHSMEGDAWgBQ3QIeJNg+2PK+k/ZrrLqaGxnpTjTANBgkqhkiG\n" + + "9w0BAQIFAANBAIX63Ypi9P71RnC/pcMbhD+wekRFsTzU593X3MC7tyBJtEXwvAZG\n" + + "iMxXF5A+ohlr7/CrkV7ZTL8PLxnJdY5Y8rQ=\n" + + "-----END CERTIFICATE-----"; + + private static CertPath generateCertificatePath(String castr, + String eestr) throws CertificateException { + // generate certificate from cert strings + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + ByteArrayInputStream is; + + is = new ByteArrayInputStream(castr.getBytes()); + Certificate cacert = cf.generateCertificate(is); + + is = new ByteArrayInputStream(eestr.getBytes()); + Certificate eecert = cf.generateCertificate(is); + + // generate certification path + List list = Arrays.asList(new Certificate[] { + eecert, cacert}); + + return cf.generateCertPath(list); + } + + private static Set generateTrustAnchors() + throws CertificateException { + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + HashSet anchors = new HashSet(); + + ByteArrayInputStream is = + new ByteArrayInputStream(trustAnchor_SHA1withRSA_1024.getBytes()); + Certificate cert = cf.generateCertificate(is); + TrustAnchor anchor = new TrustAnchor((X509Certificate)cert, null); + anchors.add(anchor); + + is = new ByteArrayInputStream(trustAnchor_SHA1withRSA_512.getBytes()); + cert = cf.generateCertificate(is); + anchor = new TrustAnchor((X509Certificate)cert, null); + anchors.add(anchor); + + return anchors; + } + + public static void main(String args[]) throws Exception { + try { + validate(endentiry_SHA1withRSA_1024_1024, + intermediate_SHA1withRSA_1024_1024); + validate(endentiry_SHA1withRSA_1024_512, + intermediate_SHA1withRSA_512_1024); + validate(endentiry_SHA1withRSA_512_1024, + intermediate_SHA1withRSA_1024_1024); + validate(endentiry_SHA1withRSA_512_512, + intermediate_SHA1withRSA_512_1024); + } catch (CertPathValidatorException cpve) { + throw new Exception( + "unexpect exception, it is valid cert", cpve); + } + + try { + validate(endentiry_MD2withRSA_1024_1024, + intermediate_SHA1withRSA_1024_1024); + throw new Exception("expected algorithm disabled exception"); + } catch (CertPathValidatorException cpve) { + System.out.println("Get the expected exception " + cpve); + } + + try { + validate(endentiry_MD2withRSA_1024_512, + intermediate_SHA1withRSA_512_1024); + throw new Exception("expected algorithm disabled exception"); + } catch (CertPathValidatorException cpve) { + System.out.println("Get the expected exception " + cpve); + } + } + + private static void validate(String eecert, String cacert) + throws CertPathValidatorException, Exception { + + CertPath path = generateCertificatePath(cacert, eecert); + Set anchors = generateTrustAnchors(); + + PKIXParameters params = new PKIXParameters(anchors); + + // disable certificate revocation checking + params.setRevocationEnabled(false); + + // set the validation time + params.setDate(new Date(109, 9, 1)); // 2009-09-01 + + CertPathValidator validator = CertPathValidator.getInstance("PKIX"); + + validator.validate(path, params); + } + +} diff --git a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorIntermediate.java b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorIntermediate.java new file mode 100644 index 00000000000..ee450f9c8a0 --- /dev/null +++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorIntermediate.java @@ -0,0 +1,256 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * + * @bug 6861062 + * @summary Disable MD2 support + * + * @author Xuelei Fan + */ + +import java.io.*; +import java.net.SocketException; +import java.util.*; +import java.security.Security; +import java.security.cert.*; + +public class CPValidatorIntermediate { + + // SHA1withRSA 1024 + static String trustAnchor_SHA1withRSA_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDRaFw0zMDA3MTcwMTExNDRa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB\n" + + "AQUAA4GNADCBiQKBgQC8UdC863pFk1Rvd7xUYd60+e9KsLhb6SqOfU42ZA715FcH\n" + + "E1TRvQPmYzAnHcO04TrWZQtO6E+E2RCmeBnetBvIMVka688QkO14wnrIrf2tRodd\n" + + "rZNZEBzkX+zyXCRo9tKEUDFf9Qze7Ilbb+Zzm9CUfu4M1Oz6iQcXRx7aM0jEAQID\n" + + "AQABo4GJMIGGMB0GA1UdDgQWBBTn0C+xmZY/BTab4W9gBp3dGa7WgjBHBgNVHSME\n" + + "QDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEwHzELMAkGA1UEBhMCVVMxEDAO\n" + + "BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAgQw\n" + + "DQYJKoZIhvcNAQEFBQADgYEAiCXL2Yp4ruyRXAIJ8zBEaPC9oV2agqgbSbly2z8z\n" + + "Ik5SeSRysP+GHBpb8uNyANJnQKv+T0GrJiTLMBjKCOiJl6xzk3EZ2wbQB6G/SQ9+\n" + + "UWcsXSC8oGSEPpkj5In/9/UbuUIfT9H8jmdyLNKQvlqgq6kyfnskME7ptGgT95Hc\n" + + "tas=\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 + static String trustAnchor_SHA1withRSA_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIBuTCCAWOgAwIBAgIBADANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDRaFw0zMDA3MTcwMTExNDRa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMFwwDQYJKoZIhvcNAQEB\n" + + "BQADSwAwSAJBAM0Kn4ieCdCHsrm78ZMMN4jQEEEqACAMKB7O8j9g4gfz2oAfmHwv\n" + + "7JH/hZ0Xen1zUmBbwe+e2J5D/4Fisp9Bn98CAwEAAaOBiTCBhjAdBgNVHQ4EFgQU\n" + + "g4Kwd47hdNQBp8grZsRJ5XvhvxAwRwYDVR0jBEAwPoAUg4Kwd47hdNQBp8grZsRJ\n" + + "5XvhvxChI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlggEAMA8G\n" + + "A1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0GCSqGSIb3DQEBBQUAA0EAn77b\n" + + "FJx+HvyRvjZYCzMjnUct3Ql4iLOkURYDh93J5TXi/l9ajvAMEuwzYj0qZ+Ktm/ia\n" + + "U5r+8B9nzx+j2Zh3kw==\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 1024 signed with RSA 1024 + static String intermediate_SHA1withRSA_1024_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICUDCCAbmgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDhaFw0yOTA0MjMwMTExNDha\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQEFBQADgYEAHze3wAcIe84zNOoN\n" + + "P8l9EmlVVoU30z3LB3hxq3m/dC/4gE5Z9Z8EG1wJw4qaxlTZ4dif12nbTTdofVhb\n" + + "Bd4syjo6fcUA4q7sfg9TFpoHQ+Ap7PgjK99moMKdMy50Xy8s6FPvaVkF89s66Z6y\n" + + "e4q7TSwe6QevGOZaL5N/iy2XGEs=\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 1024 signed with RSA 512 + static String intermediate_SHA1withRSA_1024_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICDzCCAbmgAwIBAgIBAzANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBSDgrB3juF01AGnyCtmxEnle+G/EKEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQEFBQADQQCYNmdkONfuk07XjRze\n" + + "WQyq2cfdae4uIdyUfa2rpgYMtSXuQW3/XrQGiz4G6WBXA2wo7folOOpAKYgvHPrm\n" + + "w6Dd\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 signed with RSA 1024 + static String intermediate_SHA1withRSA_512_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICDDCCAXWgAwIBAgIBBDANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKubXYoEHZpZkhzA9XX+NrpqJ4SV\n" + + "lOMBoL3aWExQpJIgrUaZfbGMBBozIHBJMMayokguHbJvq4QigEgLuhfJNqsCAwEA\n" + + "AaOBiTCBhjAdBgNVHQ4EFgQUN0CHiTYPtjyvpP2a6y6mhsZ6U40wRwYDVR0jBEAw\n" + + "PoAU59AvsZmWPwU2m+FvYAad3Rmu1oKhI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD\n" + + "VQQKEwdFeGFtcGxlggEAMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0G\n" + + "CSqGSIb3DQEBBQUAA4GBAE2VOlw5ySLT3gUzKCYEga4QPaSrf6lHHPi2g48LscEY\n" + + "h9qQXh4nuIVugReBIEf6N49RdT+M2cgRJo4sZ3ukYLGQzxNuttL5nPSuuvrAR1oG\n" + + "LUyzOWcUpKHbVHi6zlTt79RvTKZvLcduLutmtPtLJcM9PdiAI1wEooSgxTwZtB/Z\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 signed with RSA 512 + static String intermediate_SHA1withRSA_512_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIByzCCAXWgAwIBAgIBBTANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKubXYoEHZpZkhzA9XX+NrpqJ4SV\n" + + "lOMBoL3aWExQpJIgrUaZfbGMBBozIHBJMMayokguHbJvq4QigEgLuhfJNqsCAwEA\n" + + "AaOBiTCBhjAdBgNVHQ4EFgQUN0CHiTYPtjyvpP2a6y6mhsZ6U40wRwYDVR0jBEAw\n" + + "PoAUg4Kwd47hdNQBp8grZsRJ5XvhvxChI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD\n" + + "VQQKEwdFeGFtcGxlggEAMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0G\n" + + "CSqGSIb3DQEBBQUAA0EAoCf0Zu559qcB4xPpzqkVsYiyW49S4Yc0mmQXb1yoQgLx\n" + + "O+DCkjG5d14+t1MsnkhB2izoQUMxQ3vDc1YnA/tEpw==\n" + + "-----END CERTIFICATE-----"; + + // MD2withRSA 1024 signed with RSA 1024 + static String intermediate_MD2withRSA_1024_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICUDCCAbmgAwIBAgIBBjANBgkqhkiG9w0BAQIFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQECBQADgYEAPtEjwbWuC5kc4DPc\n" + + "Ttf/wdbD8ZCdAWzcc3XF9q1TlvwVMNk6mbfM05y6ZVsztKTkwZ4EcvFu/yIqw1EB\n" + + "E1zlXQCaWXT3/ZMbqYZV4+mx+RUl8spUCb1tda25jnTg3mTOzB1iztm4gy903EMd\n" + + "m8omKDKeCgcw5dR4ITQYvyxe1as=\n" + + "-----END CERTIFICATE-----"; + + // MD2withRSA 1024 signed with RSA 512 + static String intermediate_MD2withRSA_1024_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICDzCCAbmgAwIBAgIBBzANBgkqhkiG9w0BAQIFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8\n" + + "BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg\n" + + "bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82\n" + + "AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl\n" + + "UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBSDgrB3juF01AGnyCtmxEnle+G/EKEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQECBQADQQBHok1v6xymtpB7N9xy\n" + + "0OmDT27uhmzlP0eOzJvXVxj3Oi9TLQJgCUJ9122MzfRAs1E1uJTtvuu+UmI80NQx\n" + + "KQdp\n" + + "-----END CERTIFICATE-----"; + + private static CertPath generateCertificatePath(String certStr) + throws CertificateException { + // generate certificate from cert strings + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + ByteArrayInputStream is; + + is = new ByteArrayInputStream(certStr.getBytes()); + Certificate cert = cf.generateCertificate(is); + + // generate certification path + List list = Arrays.asList(new Certificate[] {cert}); + + return cf.generateCertPath(list); + } + + private static Set generateTrustAnchors() + throws CertificateException { + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + HashSet anchors = new HashSet(); + + ByteArrayInputStream is = + new ByteArrayInputStream(trustAnchor_SHA1withRSA_1024.getBytes()); + Certificate cert = cf.generateCertificate(is); + TrustAnchor anchor = new TrustAnchor((X509Certificate)cert, null); + anchors.add(anchor); + + is = new ByteArrayInputStream(trustAnchor_SHA1withRSA_512.getBytes()); + cert = cf.generateCertificate(is); + anchor = new TrustAnchor((X509Certificate)cert, null); + anchors.add(anchor); + + return anchors; + } + + public static void main(String args[]) throws Exception { + try { + validate(intermediate_SHA1withRSA_1024_1024); + validate(intermediate_SHA1withRSA_1024_512); + validate(intermediate_SHA1withRSA_512_1024); + validate(intermediate_SHA1withRSA_512_512); + } catch (CertPathValidatorException cpve) { + throw new Exception( + "unexpect exception, it is valid cert", cpve); + } + + try { + validate(intermediate_MD2withRSA_1024_1024); + throw new Exception("expected algorithm disabled exception"); + } catch (CertPathValidatorException cpve) { + System.out.println("Get the expected exception " + cpve); + } + + try { + validate(intermediate_MD2withRSA_1024_512); + throw new Exception("expected algorithm disabled exception"); + } catch (CertPathValidatorException cpve) { + System.out.println("Get the expected exception " + cpve); + } + } + + private static void validate(String intermediate) + throws CertPathValidatorException, Exception { + + CertPath path = generateCertificatePath(intermediate); + Set anchors = generateTrustAnchors(); + + PKIXParameters params = new PKIXParameters(anchors); + + // disable certificate revocation checking + params.setRevocationEnabled(false); + + // set the validation time + params.setDate(new Date(109, 9, 1)); // 2009-09-01 + + CertPathValidator validator = CertPathValidator.getInstance("PKIX"); + + validator.validate(path, params); + } + +} diff --git a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorTrustAnchor.java b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorTrustAnchor.java new file mode 100644 index 00000000000..1aeac579e30 --- /dev/null +++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorTrustAnchor.java @@ -0,0 +1,169 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * + * @bug 6861062 + * @summary Disable MD2 support + * + * @author Xuelei Fan + */ + +import java.io.*; +import java.net.SocketException; +import java.util.*; +import java.security.Security; +import java.security.cert.*; + +public class CPValidatorTrustAnchor { + + static String selfSignedCertStr = null; + + // SHA1withRSA 1024 + static String trustAnchor_SHA1withRSA_1024 = + "-----BEGIN CERTIFICATE-----\n" + + "MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDRaFw0zMDA3MTcwMTExNDRa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB\n" + + "AQUAA4GNADCBiQKBgQC8UdC863pFk1Rvd7xUYd60+e9KsLhb6SqOfU42ZA715FcH\n" + + "E1TRvQPmYzAnHcO04TrWZQtO6E+E2RCmeBnetBvIMVka688QkO14wnrIrf2tRodd\n" + + "rZNZEBzkX+zyXCRo9tKEUDFf9Qze7Ilbb+Zzm9CUfu4M1Oz6iQcXRx7aM0jEAQID\n" + + "AQABo4GJMIGGMB0GA1UdDgQWBBTn0C+xmZY/BTab4W9gBp3dGa7WgjBHBgNVHSME\n" + + "QDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEwHzELMAkGA1UEBhMCVVMxEDAO\n" + + "BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAgQw\n" + + "DQYJKoZIhvcNAQEFBQADgYEAiCXL2Yp4ruyRXAIJ8zBEaPC9oV2agqgbSbly2z8z\n" + + "Ik5SeSRysP+GHBpb8uNyANJnQKv+T0GrJiTLMBjKCOiJl6xzk3EZ2wbQB6G/SQ9+\n" + + "UWcsXSC8oGSEPpkj5In/9/UbuUIfT9H8jmdyLNKQvlqgq6kyfnskME7ptGgT95Hc\n" + + "tas=\n" + + "-----END CERTIFICATE-----"; + + // SHA1withRSA 512 + static String trustAnchor_SHA1withRSA_512 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIBuTCCAWOgAwIBAgIBADANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDRaFw0zMDA3MTcwMTExNDRa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMFwwDQYJKoZIhvcNAQEB\n" + + "BQADSwAwSAJBAM0Kn4ieCdCHsrm78ZMMN4jQEEEqACAMKB7O8j9g4gfz2oAfmHwv\n" + + "7JH/hZ0Xen1zUmBbwe+e2J5D/4Fisp9Bn98CAwEAAaOBiTCBhjAdBgNVHQ4EFgQU\n" + + "g4Kwd47hdNQBp8grZsRJ5XvhvxAwRwYDVR0jBEAwPoAUg4Kwd47hdNQBp8grZsRJ\n" + + "5XvhvxChI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlggEAMA8G\n" + + "A1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0GCSqGSIb3DQEBBQUAA0EAn77b\n" + + "FJx+HvyRvjZYCzMjnUct3Ql4iLOkURYDh93J5TXi/l9ajvAMEuwzYj0qZ+Ktm/ia\n" + + "U5r+8B9nzx+j2Zh3kw==\n" + + "-----END CERTIFICATE-----"; + + // MD2withRSA 2048 + static String trustAnchor_MD2withRSA_2048 = + "-----BEGIN CERTIFICATE-----\n" + + "MIIDQzCCAiugAwIBAgIBADANBgkqhkiG9w0BAQIFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDdaFw0zMDA3MTcwMTExNDda\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIIBIjANBgkqhkiG9w0B\n" + + "AQEFAAOCAQ8AMIIBCgKCAQEArF5pINc5s+aUlmdYlxtAQ3V4TXFnP/XOYHxjfLuX\n" + + "eKO/kh78LMvbDisTPQ2yo9YEawwwbUU40xcuzgi0axXgKveHXYdUmTr0hEapq3rv\n" + + "g/q2EbOjyXvq4qK2RDoVCN8R3wXiytnY2OFALTx6zc2tW4imJ20svdNVtWhv2syj\n" + + "ZTmmRXAeFUbD4qKWAFij0I6pnSgVssvWzeyJUNemym+oiYyaSd7n5j1RNAqUKioo\n" + + "K/T0FOOiuPGMqottgx5YRHa6yapCP5QVWRQ+WBIYJY3Wyq7N+Es20LT6761Pk3to\n" + + "EFCzM7+zqT/c+pC079HOKXz+m2us+HKp5BKWNnbvgaYPOQIDAQABo4GJMIGGMB0G\n" + + "A1UdDgQWBBSrSukJf+mO5LTRasAGD9RRs7SASTBHBgNVHSMEQDA+gBSrSukJf+mO\n" + + "5LTRasAGD9RRs7SASaEjpCEwHzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1w\n" + + "bGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQEC\n" + + "BQADggEBAHvsv+DqMJeIW/D+ltkhw37OdMzkMPp4E6Hbp03O3GZ5LfNGczHCb2uL\n" + + "sr5T7e/jaBFn6QfmqbOAYAHJSNq2bNNtTbatnHBLuVx13cfxmwk89Cg/tFeoUdcf\n" + + "m5hzurB6Ub6SsYMOxZHUYp/KxM9x9a7llC1bK3SKXwd4rVDlXh8DOBvdQNr5Q3yq\n" + + "JjY86bSXO14VzNxL/1rqHiszQdPyR/28SBsQVYSi0Zeyc4Yy1ui/cXu1+PWYw3YZ\n" + + "QUPHTnkVdPGwRiUqeZIcps+q+ePlQQmDu5qiLD6d8gsyGyY/RvCHWKO5Y9DuX9hs\n" + + "he/AhCWQx+TQYGLu0liQqLkGZydyRnA=\n" + + "-----END CERTIFICATE-----"; + + private static CertPath generateCertificatePath() + throws CertificateException { + // generate certificate from cert strings + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + ByteArrayInputStream is; + + is = new ByteArrayInputStream(selfSignedCertStr.getBytes()); + Certificate selfSignedCert = cf.generateCertificate(is); + + // generate certification path + List list = Arrays.asList(new Certificate[] { + selfSignedCert}); + + return cf.generateCertPath(list); + } + + private static Set generateTrustAnchors() + throws CertificateException { + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + ByteArrayInputStream is = + new ByteArrayInputStream(selfSignedCertStr.getBytes()); + Certificate selfSignedCert = cf.generateCertificate(is); + + // generate a trust anchor + TrustAnchor anchor = + new TrustAnchor((X509Certificate)selfSignedCert, null); + + return Collections.singleton(anchor); + } + + public static void main(String args[]) throws Exception { + try { + validate(trustAnchor_SHA1withRSA_1024); + validate(trustAnchor_SHA1withRSA_512); + } catch (CertPathValidatorException cpve) { + throw new Exception( + "unexpect exception, it is valid cert", cpve); + } + + try { + validate(trustAnchor_MD2withRSA_2048); + throw new Exception("expected algorithm disabled exception"); + } catch (CertPathValidatorException cpve) { + System.out.println("Get the expected exception " + cpve); + } + } + + private static void validate(String trustAnchor) + throws CertPathValidatorException, Exception { + selfSignedCertStr = trustAnchor; + + CertPath path = generateCertificatePath(); + Set anchors = generateTrustAnchors(); + + PKIXParameters params = new PKIXParameters(anchors); + + // disable certificate revocation checking + params.setRevocationEnabled(false); + + // set the validation time + params.setDate(new Date(109, 9, 1)); // 2009-09-01 + + CertPathValidator validator = CertPathValidator.getInstance("PKIX"); + + validator.validate(path, params); + } + +} diff --git a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/README b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/README new file mode 100644 index 00000000000..6577db95210 --- /dev/null +++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/README @@ -0,0 +1,640 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + Certificates and CRLs + +Here lists the Certificates, which was generated by generate.sh, used in the +test cases. + +The generate.sh depends on openssl, and it should be run under ksh. The +script will create many directories and files, please run it in a +directory outside of JDK workspace. + +1. root certifiate and key (SHA1withRSA 1024, root_cert_sha1_1024.pem) +-----BEGIN CERTIFICATE----- +MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDRaFw0zMDA3MTcwMTExNDRa +MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQC8UdC863pFk1Rvd7xUYd60+e9KsLhb6SqOfU42ZA715FcH +E1TRvQPmYzAnHcO04TrWZQtO6E+E2RCmeBnetBvIMVka688QkO14wnrIrf2tRodd +rZNZEBzkX+zyXCRo9tKEUDFf9Qze7Ilbb+Zzm9CUfu4M1Oz6iQcXRx7aM0jEAQID +AQABo4GJMIGGMB0GA1UdDgQWBBTn0C+xmZY/BTab4W9gBp3dGa7WgjBHBgNVHSME +QDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEwHzELMAkGA1UEBhMCVVMxEDAO +BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAgQw +DQYJKoZIhvcNAQEFBQADgYEAiCXL2Yp4ruyRXAIJ8zBEaPC9oV2agqgbSbly2z8z +Ik5SeSRysP+GHBpb8uNyANJnQKv+T0GrJiTLMBjKCOiJl6xzk3EZ2wbQB6G/SQ9+ +UWcsXSC8oGSEPpkj5In/9/UbuUIfT9H8jmdyLNKQvlqgq6kyfnskME7ptGgT95Hc +tas= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,DF5249E009A0FD79 + +rc316yLipp/vH0i6rhEbEwZpZ+HfKIXnnp/bIIZv2+4lyGUDWrxN0Hk0TcSgWEKm +dRGI2fsyWjTgaiHwwmusofXPAjB3s0I2rUUAHXk8/sEuiLLTICx2UAL8k6R33CSQ +NKR8t+TluBW3Us71vibWauuMHa5860KiiLWdhkQVLin7m/JBGLtz0zQ0/lZ8CgEm +p7eDupPi8FBClCyVewdpmKjgI2KPI4fVIZLMzLeGcWLaOQPN1ERcFWQ1CS/qjfMb +F4rtpZ+AzCqP75XPhitT2CnZgaVDxHBtAZQVPuKONMdijKphjqiT/Sd86Gx6OEVE +EwwmQya2Q/5aCuH96S00mj00oeIZ7ZtUcVQcch+saJy4vpuxK8pFcEDKmgsvL9+8 +Hho9RUXVUKRH67uA1NjQSK5+syEIj5sJCDcxOda4QGXeIq9ygaZswxF3nfvffrsa +S6IVBXrx0G+Ascu29SHoI+zi3feQszQJIzijHoTTq6FacLHUWzfVuaYa47uaj5qa +VYsMVCzi1eX486o7YKPKWiclNczQN86v5n9+c9uggXY12wSOmnf6BB1Ds+oL8JlU +IZa67lAyg6G9joAb9rTXN2EE5OTArcFuImK8GHse/3wkIPMglBNnfwpvjC1U+vQm +F7iXp+OxnZ5d9sBcrTBEZ9BDlTVlpiZI7EeS1oC8x6DDTdbJR/40Y3wJIDMI9q9T +O5EnyXqbmQziO0Tgal43w6mMTUnhG34kqovwxy03mAOZb3yz/RgWlez9wQmPseiI +2p2fQIjCPbGFNJt3rdyXOW/BRCii0970HEZeov/TVV/A0vUVajNAjA== +-----END RSA PRIVATE KEY----- + +2. root certifiate and key (SHA1withRSA 512, root_cert_sha1_512.pem) +-----BEGIN CERTIFICATE----- +MIIBuTCCAWOgAwIBAgIBADANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDRaFw0zMDA3MTcwMTExNDRa +MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMFwwDQYJKoZIhvcNAQEB +BQADSwAwSAJBAM0Kn4ieCdCHsrm78ZMMN4jQEEEqACAMKB7O8j9g4gfz2oAfmHwv +7JH/hZ0Xen1zUmBbwe+e2J5D/4Fisp9Bn98CAwEAAaOBiTCBhjAdBgNVHQ4EFgQU +g4Kwd47hdNQBp8grZsRJ5XvhvxAwRwYDVR0jBEAwPoAUg4Kwd47hdNQBp8grZsRJ +5XvhvxChI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlggEAMA8G +A1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0GCSqGSIb3DQEBBQUAA0EAn77b +FJx+HvyRvjZYCzMjnUct3Ql4iLOkURYDh93J5TXi/l9ajvAMEuwzYj0qZ+Ktm/ia +U5r+8B9nzx+j2Zh3kw== +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,B8BDE38F08C6BB76 + +eJzx2oZE0UXxWpzssSWtKBOCbm3ZXR6iBKX8iKoDUB5SzzmKr+XzxI7kyv92y0pe +rNTuuCWpBsLdlz7h8Ipn4pBDYswGU5F9MQOEgIYx60OvGhZODHGRzJ05FXTeCmmu +LLp6lGW4SWALcd8g/gJUn1/vp7f1VzQ7RwXWBn4/b34RRYtwr3E6nl4Hc2tEI1in +OL+lCdAAyxjGK7KYFHJQK+1E8tYNrer3cejQDcNysGx4o0H123vfp3NtJ6U7LXyi +D21y3zmPueJos8LluJiLRsONcrcI3mIfpPBsO+Yl2EJtzS9V6Aaq/YdPkwPHH6Y5 +lazGMPXq/nffb12fWLL7m5aFb3FNLwWi/qwEynWCEv7Vl/6kLk+aHhjTnYkLvLNH +9maQFn6j0S3wqogRfW9BDbfC3fRHP6+8YjEEmQ0RTfE= +-----END RSA PRIVATE KEY----- + +3. root certifiate and key (MD2withRSA 2048, root_cert_md2_2048.pem) +-----BEGIN CERTIFICATE----- +MIIDQzCCAiugAwIBAgIBADANBgkqhkiG9w0BAQIFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDdaFw0zMDA3MTcwMTExNDda +MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEArF5pINc5s+aUlmdYlxtAQ3V4TXFnP/XOYHxjfLuX +eKO/kh78LMvbDisTPQ2yo9YEawwwbUU40xcuzgi0axXgKveHXYdUmTr0hEapq3rv +g/q2EbOjyXvq4qK2RDoVCN8R3wXiytnY2OFALTx6zc2tW4imJ20svdNVtWhv2syj +ZTmmRXAeFUbD4qKWAFij0I6pnSgVssvWzeyJUNemym+oiYyaSd7n5j1RNAqUKioo +K/T0FOOiuPGMqottgx5YRHa6yapCP5QVWRQ+WBIYJY3Wyq7N+Es20LT6761Pk3to +EFCzM7+zqT/c+pC079HOKXz+m2us+HKp5BKWNnbvgaYPOQIDAQABo4GJMIGGMB0G +A1UdDgQWBBSrSukJf+mO5LTRasAGD9RRs7SASTBHBgNVHSMEQDA+gBSrSukJf+mO +5LTRasAGD9RRs7SASaEjpCEwHzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1w +bGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQEC +BQADggEBAHvsv+DqMJeIW/D+ltkhw37OdMzkMPp4E6Hbp03O3GZ5LfNGczHCb2uL +sr5T7e/jaBFn6QfmqbOAYAHJSNq2bNNtTbatnHBLuVx13cfxmwk89Cg/tFeoUdcf +m5hzurB6Ub6SsYMOxZHUYp/KxM9x9a7llC1bK3SKXwd4rVDlXh8DOBvdQNr5Q3yq +JjY86bSXO14VzNxL/1rqHiszQdPyR/28SBsQVYSi0Zeyc4Yy1ui/cXu1+PWYw3YZ +QUPHTnkVdPGwRiUqeZIcps+q+ePlQQmDu5qiLD6d8gsyGyY/RvCHWKO5Y9DuX9hs +he/AhCWQx+TQYGLu0liQqLkGZydyRnA= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,3910D329AD49ECFC + +6K0OU3Xrl2H6kz7x7EHXkM0/Wd6jXBBwWsaroUIGnbIMmljJXPfgcuDUu6f5Imk1 +ndoU0GWjxa1QNjteAQQtFoLDP8rienLs0b969OcAxB0EOffQFkEfsfXdyEIgdwkD +ETczwDIyd8Wj62ClydJES3jKB9Nc9kMIlsoZ+h24TyJeeRsHAtMrz+mlOHsUWDQ5 +FyYZelnx+fQ5maD3bura7xLiNl8CvgWz0wt2Wt4djdMGhQ3OWd0/GWweP+2xnL6n +5tDJ5On50+Z5T8Jhx62yg+wQiBKAYnYw6OX3skJwWknuAvYz3Z3e12DHFx6w5EAU +K7lg7fHMqHNirUkJOlYzgJ21ybV4uQmFRNQJwI9h6GVfdZWPEU+Ni42AlNgNYskF +K19dONNNt0Gwkcm2VOYzwYGDyaQW2YIGDk1fbZdVSu/h/lyOC/RmorGWroAbYsyB +/GUIilcLtQHPGI8XuojTS2/UWcKactpceN3UOnQkus3/smViEqqB/NQ/lcozgs0o +7ZG6H6to7w1yb5VR2d7B2bS7MNJt1AsOB5ydAMYIccdHDTI7CfRK6axQ70O/JPnJ +WLY2e41ig2uAWk/3fRb8L6d3keVcN7y4WnkXPbHhulqtxQo78iSQQAf7tDMBxWKx +C5LQW3CxLkHKp6g22SDxl2LjJyu5nDbtIh3Pq+BCoA25uqXC4rPoWwV7EWYv8Z+Y +E6dS98SEa+cDhpllvGzbTKgcP1VqtQbb9VT92UT1mFrklqRuQIxROeCe4wjp5TKo +D2losUDdzpqBHkBNo2I8qZkgybeCvWEq73my2+JG1AAIFFB1kzfBNaBDGiGSuUuS +5peV8156aaLg5pxdieoRJ3Y7eaWN1wH5CnRnafoB+lxSUsQO1a7y2LbpedrKjs+2 +AryPHQw7HLd8IQevmvd7BhJLdvlt+kXzWID/pUsSAYvI7aP4daQJuAt/kwmU27Gd +wqhV8Tjbb84vFGmqGHtb2YbKfUrsPUNOLBF+U4SDAgBhEyhINQZyRDcqqoywO5Dr +sV46nTEfwAgt88KFt2CEhiyvoJbtCj1iMJeAzuljwF4z4RzB1i3TK0MaJYID2rxB +E1vK9EZIssk/NeImN2YCbuqOhU58jtOwYh3ruS+mZQm1APvJF9N4tCCVQsjWC6zY +4eqs7T6VDFH4AaT7b3J3rTsEpWIDUfagetZs5kR9SiWJC7dU7r53gGg4avVyIIHD ++MYCS+auD9/nmVf4iYstVgJFMUJXC2EUOLi0r8KmDkCILl/K3X/W7QwFTnC07gLh +/9HjWFJ0R6cyODzvE8NGPMeuJGUT2F+mA1vaAC/PBGz+61AF0BjWTZ7x2sH+tSPP +/GVEaCgyzrKRX5XX+7DulTcmFj1JNfMmtbDaJa9WnwOI4qszBGrAcYeYTHXR6Yov +Ux/P6RStfa+UwSjo8i3nfdgLk+RXCpN0srMjSmiQx8d5R/kISqXKDtQfS5M6gsoh +ROz+6zZP8Gh8yakr1p4C6JUSiLDYP5qXzxr8bp+oxvpY7anEDAqx21HyExEAu+gy +IrNl75FWqV8BbKxoFfe9LqyDaryXXA8oy6F+4BT/zRrxp+dym9pbd+OZR423BIij +-----END RSA PRIVATE KEY----- + +4. subca certificate and key (SHA1withRSA 1024, root_cert_sha1_1024.pem signed) +-----BEGIN CERTIFICATE----- +MIICUDCCAbmgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDhaFw0yOTA0MjMwMTExNDha +MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz +cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8 +BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg +bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82 +AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl +UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEw +HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw +AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQEFBQADgYEAHze3wAcIe84zNOoN +P8l9EmlVVoU30z3LB3hxq3m/dC/4gE5Z9Z8EG1wJw4qaxlTZ4dif12nbTTdofVhb +Bd4syjo6fcUA4q7sfg9TFpoHQ+Ap7PgjK99moMKdMy50Xy8s6FPvaVkF89s66Z6y +e4q7TSwe6QevGOZaL5N/iy2XGEs= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,0480E76FD259323B + +npiifBm1mHq1Z9QgAV5T35Xbnea9VnwqYQWNfRRKmpfYSdkQJ0few18YtnfZwh9e +LKCWx+lq1V4yDG4SbxXDq71Dyvx1vZY+w4h+6M1+6KGFG1VDBfN3e5aLgK8EG9pZ +yHZH7iB7HiQXH5q53jL6NUZn55C3XEk1sErpK7R1c0Y8Qp2TGiu+lck3K+zR9GiO +5aJMKbShReB0Nfy3JJNKRFSd95QMTTjbq6iIvhN8O02bo4I4I3HTyD8qyR7ViiHl +FmOukjwn4fjJvK0WYKYUjod8oEiMdR2nr73eOGZBAnEorDGQ8VnnCAleSv74is1k +W7M07UP7EJJq9hSZfeMqk5QivtWrqvWG1SWxpTowKTEAyTn7u5U13k0DiRcsg0WT +4mSMiLOhUNgIWcHElbTQPSVDcVznhNk0dWPDwKoUjp+orCuH+NvHKBAu+hnuip3e +Ji7WGrHXI7QxAr5qr5ogl5x4yH4drIbq9fUea3NTuGPuPyu9fWjOSDmqPRKRMJFR +UxxVFcyrW8iSBV5cvB7M1ADS40y6l4ryYmKjXbsOI4Ci8LJWJ4ZB61WQP7TvPQGS +mNFmTTB2dwbpimr4KjV9j2bA9x0jAsjlcQZ5j1GOeyYCEDGKDJw0XD/zI+j0dpVc +eu8YtuJGTyO1h+HiI3D9LrMuyUxxckvFHKe00+4xMz1hpqVo/kxe6gqf/9ES4M/h +6/NeTzeqyJF2rgxK6KJJdmaKVYI+bvAQ3cKl+RZmgOjx4eig58N5uthqFgU7rQ+e +GM9/y8C9WpPqITcJlY7I/7AkqvYDBwBsH/9mf4g9OUbC1Ah+MX8UIQ== +-----END RSA PRIVATE KEY----- + + +5. subca certificate and key (SHA1withRSA 1024, root_cert_sha1_512.pem signed) +-----BEGIN CERTIFICATE----- +MIICDzCCAbmgAwIBAgIBAzANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla +MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz +cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8 +BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg +bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82 +AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl +UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBSDgrB3juF01AGnyCtmxEnle+G/EKEjpCEw +HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw +AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQEFBQADQQCYNmdkONfuk07XjRze +WQyq2cfdae4uIdyUfa2rpgYMtSXuQW3/XrQGiz4G6WBXA2wo7folOOpAKYgvHPrm +w6Dd +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,0480E76FD259323B + +npiifBm1mHq1Z9QgAV5T35Xbnea9VnwqYQWNfRRKmpfYSdkQJ0few18YtnfZwh9e +LKCWx+lq1V4yDG4SbxXDq71Dyvx1vZY+w4h+6M1+6KGFG1VDBfN3e5aLgK8EG9pZ +yHZH7iB7HiQXH5q53jL6NUZn55C3XEk1sErpK7R1c0Y8Qp2TGiu+lck3K+zR9GiO +5aJMKbShReB0Nfy3JJNKRFSd95QMTTjbq6iIvhN8O02bo4I4I3HTyD8qyR7ViiHl +FmOukjwn4fjJvK0WYKYUjod8oEiMdR2nr73eOGZBAnEorDGQ8VnnCAleSv74is1k +W7M07UP7EJJq9hSZfeMqk5QivtWrqvWG1SWxpTowKTEAyTn7u5U13k0DiRcsg0WT +4mSMiLOhUNgIWcHElbTQPSVDcVznhNk0dWPDwKoUjp+orCuH+NvHKBAu+hnuip3e +Ji7WGrHXI7QxAr5qr5ogl5x4yH4drIbq9fUea3NTuGPuPyu9fWjOSDmqPRKRMJFR +UxxVFcyrW8iSBV5cvB7M1ADS40y6l4ryYmKjXbsOI4Ci8LJWJ4ZB61WQP7TvPQGS +mNFmTTB2dwbpimr4KjV9j2bA9x0jAsjlcQZ5j1GOeyYCEDGKDJw0XD/zI+j0dpVc +eu8YtuJGTyO1h+HiI3D9LrMuyUxxckvFHKe00+4xMz1hpqVo/kxe6gqf/9ES4M/h +6/NeTzeqyJF2rgxK6KJJdmaKVYI+bvAQ3cKl+RZmgOjx4eig58N5uthqFgU7rQ+e +GM9/y8C9WpPqITcJlY7I/7AkqvYDBwBsH/9mf4g9OUbC1Ah+MX8UIQ== +-----END RSA PRIVATE KEY----- + + +6. subca certificate and key (SHA1withRSA 512, root_cert_sha1_1024.pem signed) +-----BEGIN CERTIFICATE----- +MIICDDCCAXWgAwIBAgIBBDANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla +MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz +cy0xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKubXYoEHZpZkhzA9XX+NrpqJ4SV +lOMBoL3aWExQpJIgrUaZfbGMBBozIHBJMMayokguHbJvq4QigEgLuhfJNqsCAwEA +AaOBiTCBhjAdBgNVHQ4EFgQUN0CHiTYPtjyvpP2a6y6mhsZ6U40wRwYDVR0jBEAw +PoAU59AvsZmWPwU2m+FvYAad3Rmu1oKhI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD +VQQKEwdFeGFtcGxlggEAMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0G +CSqGSIb3DQEBBQUAA4GBAE2VOlw5ySLT3gUzKCYEga4QPaSrf6lHHPi2g48LscEY +h9qQXh4nuIVugReBIEf6N49RdT+M2cgRJo4sZ3ukYLGQzxNuttL5nPSuuvrAR1oG +LUyzOWcUpKHbVHi6zlTt79RvTKZvLcduLutmtPtLJcM9PdiAI1wEooSgxTwZtB/Z +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,0A94F7EA4C89CA33 + +tfKdAZVSrpeS/hU4+mGYcGGx3nNqrE+CzDAfLadVuXz5ju5p9oFhLTZj99wK+uHn +prrWmDNOdYKRBJn7h40WV6zi4lR3JgnuYNxH8fxO3PI+HQ9IuvdoTyqUeXTP4Zj1 +BCnr1k1D2WGDXvnh+saq9qRpMKThjK/OF0YmDa07PI5NOBdMA3EmkNYfwib2GfBV +el4FVkfnPQkLGahTh3SC62TzPlnsAgirCeua7ZLPqN3fkZkYbXZd9op2D31n7cBP +zztg0ah8WF4gPOd/BBZeR9XDog5qm/wzyBj0F6ClHRPjpGYhAm2Vw66xOBlGFYI9 +lVmFQzrPcDNlFTybzhl5C6Qy4cPQh+QErDWxljVI52oYYmY/KRmUGGL7hEG8ZGOn +EUgFrEJyAY7w4wpBC5n9SotwyPXhwKQ1uCBq+1zElPw= +-----END RSA PRIVATE KEY----- + +7. subca certificate and key (SHA1withRSA 512, root_cert_sha1_512.pem signed) +-----BEGIN CERTIFICATE----- +MIIByzCCAXWgAwIBAgIBBTANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla +MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz +cy0xMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKubXYoEHZpZkhzA9XX+NrpqJ4SV +lOMBoL3aWExQpJIgrUaZfbGMBBozIHBJMMayokguHbJvq4QigEgLuhfJNqsCAwEA +AaOBiTCBhjAdBgNVHQ4EFgQUN0CHiTYPtjyvpP2a6y6mhsZ6U40wRwYDVR0jBEAw +PoAUg4Kwd47hdNQBp8grZsRJ5XvhvxChI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD +VQQKEwdFeGFtcGxlggEAMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgIEMA0G +CSqGSIb3DQEBBQUAA0EAoCf0Zu559qcB4xPpzqkVsYiyW49S4Yc0mmQXb1yoQgLx +O+DCkjG5d14+t1MsnkhB2izoQUMxQ3vDc1YnA/tEpw== +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,0A94F7EA4C89CA33 + +tfKdAZVSrpeS/hU4+mGYcGGx3nNqrE+CzDAfLadVuXz5ju5p9oFhLTZj99wK+uHn +prrWmDNOdYKRBJn7h40WV6zi4lR3JgnuYNxH8fxO3PI+HQ9IuvdoTyqUeXTP4Zj1 +BCnr1k1D2WGDXvnh+saq9qRpMKThjK/OF0YmDa07PI5NOBdMA3EmkNYfwib2GfBV +el4FVkfnPQkLGahTh3SC62TzPlnsAgirCeua7ZLPqN3fkZkYbXZd9op2D31n7cBP +zztg0ah8WF4gPOd/BBZeR9XDog5qm/wzyBj0F6ClHRPjpGYhAm2Vw66xOBlGFYI9 +lVmFQzrPcDNlFTybzhl5C6Qy4cPQh+QErDWxljVI52oYYmY/KRmUGGL7hEG8ZGOn +EUgFrEJyAY7w4wpBC5n9SotwyPXhwKQ1uCBq+1zElPw= +-----END RSA PRIVATE KEY----- + +8. subca certificate and key (MD2withRSA 1024, root_cert_sha1_1024.pem signed) +-----BEGIN CERTIFICATE----- +MIICUDCCAbmgAwIBAgIBBjANBgkqhkiG9w0BAQIFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla +MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz +cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8 +BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg +bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82 +AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl +UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBTn0C+xmZY/BTab4W9gBp3dGa7WgqEjpCEw +HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw +AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQECBQADgYEAPtEjwbWuC5kc4DPc +Ttf/wdbD8ZCdAWzcc3XF9q1TlvwVMNk6mbfM05y6ZVsztKTkwZ4EcvFu/yIqw1EB +E1zlXQCaWXT3/ZMbqYZV4+mx+RUl8spUCb1tda25jnTg3mTOzB1iztm4gy903EMd +m8omKDKeCgcw5dR4ITQYvyxe1as= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,0480E76FD259323B + +npiifBm1mHq1Z9QgAV5T35Xbnea9VnwqYQWNfRRKmpfYSdkQJ0few18YtnfZwh9e +LKCWx+lq1V4yDG4SbxXDq71Dyvx1vZY+w4h+6M1+6KGFG1VDBfN3e5aLgK8EG9pZ +yHZH7iB7HiQXH5q53jL6NUZn55C3XEk1sErpK7R1c0Y8Qp2TGiu+lck3K+zR9GiO +5aJMKbShReB0Nfy3JJNKRFSd95QMTTjbq6iIvhN8O02bo4I4I3HTyD8qyR7ViiHl +FmOukjwn4fjJvK0WYKYUjod8oEiMdR2nr73eOGZBAnEorDGQ8VnnCAleSv74is1k +W7M07UP7EJJq9hSZfeMqk5QivtWrqvWG1SWxpTowKTEAyTn7u5U13k0DiRcsg0WT +4mSMiLOhUNgIWcHElbTQPSVDcVznhNk0dWPDwKoUjp+orCuH+NvHKBAu+hnuip3e +Ji7WGrHXI7QxAr5qr5ogl5x4yH4drIbq9fUea3NTuGPuPyu9fWjOSDmqPRKRMJFR +UxxVFcyrW8iSBV5cvB7M1ADS40y6l4ryYmKjXbsOI4Ci8LJWJ4ZB61WQP7TvPQGS +mNFmTTB2dwbpimr4KjV9j2bA9x0jAsjlcQZ5j1GOeyYCEDGKDJw0XD/zI+j0dpVc +eu8YtuJGTyO1h+HiI3D9LrMuyUxxckvFHKe00+4xMz1hpqVo/kxe6gqf/9ES4M/h +6/NeTzeqyJF2rgxK6KJJdmaKVYI+bvAQ3cKl+RZmgOjx4eig58N5uthqFgU7rQ+e +GM9/y8C9WpPqITcJlY7I/7AkqvYDBwBsH/9mf4g9OUbC1Ah+MX8UIQ== +-----END RSA PRIVATE KEY----- + + +9. subca certificate and key (MD2withRSA 1024, root_cert_sha1_512.pem signed) +-----BEGIN CERTIFICATE----- +MIICDzCCAbmgAwIBAgIBBzANBgkqhkiG9w0BAQIFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDYwMTExNDlaFw0yOTA0MjMwMTExNDla +MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz +cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVOqnlZspyAEr90ELFaUo8 +BF0O2Kn0yTdUeyiLOth4RA3qxWrjxJq45VmEBjZpEzPHfnp3PhnfmLcLfhoPONFg +bcHzlkj75ZaKCgHoyV456fMBmj348fcoUkH2WdSQ82pmxHOiHqquYNUSTimFIq82 +AayhbKqDmhfx5lJdYNqd5QIDAQABo4GJMIGGMB0GA1UdDgQWBBTfWD9mRTppcUAl +UqGuu/R5t8CB5jBHBgNVHSMEQDA+gBSDgrB3juF01AGnyCtmxEnle+G/EKEjpCEw +HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw +AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQECBQADQQBHok1v6xymtpB7N9xy +0OmDT27uhmzlP0eOzJvXVxj3Oi9TLQJgCUJ9122MzfRAs1E1uJTtvuu+UmI80NQx +KQdp +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,0480E76FD259323B + +npiifBm1mHq1Z9QgAV5T35Xbnea9VnwqYQWNfRRKmpfYSdkQJ0few18YtnfZwh9e +LKCWx+lq1V4yDG4SbxXDq71Dyvx1vZY+w4h+6M1+6KGFG1VDBfN3e5aLgK8EG9pZ +yHZH7iB7HiQXH5q53jL6NUZn55C3XEk1sErpK7R1c0Y8Qp2TGiu+lck3K+zR9GiO +5aJMKbShReB0Nfy3JJNKRFSd95QMTTjbq6iIvhN8O02bo4I4I3HTyD8qyR7ViiHl +FmOukjwn4fjJvK0WYKYUjod8oEiMdR2nr73eOGZBAnEorDGQ8VnnCAleSv74is1k +W7M07UP7EJJq9hSZfeMqk5QivtWrqvWG1SWxpTowKTEAyTn7u5U13k0DiRcsg0WT +4mSMiLOhUNgIWcHElbTQPSVDcVznhNk0dWPDwKoUjp+orCuH+NvHKBAu+hnuip3e +Ji7WGrHXI7QxAr5qr5ogl5x4yH4drIbq9fUea3NTuGPuPyu9fWjOSDmqPRKRMJFR +UxxVFcyrW8iSBV5cvB7M1ADS40y6l4ryYmKjXbsOI4Ci8LJWJ4ZB61WQP7TvPQGS +mNFmTTB2dwbpimr4KjV9j2bA9x0jAsjlcQZ5j1GOeyYCEDGKDJw0XD/zI+j0dpVc +eu8YtuJGTyO1h+HiI3D9LrMuyUxxckvFHKe00+4xMz1hpqVo/kxe6gqf/9ES4M/h +6/NeTzeqyJF2rgxK6KJJdmaKVYI+bvAQ3cKl+RZmgOjx4eig58N5uthqFgU7rQ+e +GM9/y8C9WpPqITcJlY7I/7AkqvYDBwBsH/9mf4g9OUbC1Ah+MX8UIQ== +-----END RSA PRIVATE KEY----- + + +a. end entity certificate and key + (SHA1withRSA 1024, subca_cert_sha1_1024_1024.pem signed) +-----BEGIN CERTIFICATE----- +MIICNzCCAaCgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx +NTBaFw0yOTA0MjMwMTExNTBaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt +cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt +vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v +z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6 +c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07 +OorBleV92TAfBgNVHSMEGDAWgBTfWD9mRTppcUAlUqGuu/R5t8CB5jANBgkqhkiG +9w0BAQUFAAOBgQAOfIeasDg91CR3jGfuAEVKwncM1OPFmniAUcdPm74cCAyJ90Me +dhUElWPGoAuXGfiyZlOlGUYWqEroe/dnkmnotJjLWR+MA4ZyX3O1YI8T4W3deWcC +J4WMCF7mp17SaYYKX9F0AxwNJFpUkbB41IkTxPr0MmzB1871/pbY8dLAvA== +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,1FE5A37B770AF83D + +042bWtt4q0cB8pRuPUlMVncTP/WAz+mmPw3jXI3LFOBZeK6zFEDpI5M9c2JO+rqp +Za5UkYuIg69V7LngriqRynkRGGQp3xASMLr5NVbKHTE/Ol/iIuxKaCkumZmGXB/z +8bxQF5XN4tbKT4s3sWWmmKMicg6MHvySi3QVRG11PHRu/q7CEFPzJKRQ3fpaNcKD +NTBI5F6GP9ENa/eog4WGENjXS0v4Wa3IfaOhjKXrSxjLUqLH0C8g5WWg5IrXXtuI +pgyJ2kkE3Y/ChU7p7R42we6tBZqF5SiL5kFDn86DmHgCslTiZkIoE5i644sp03Sd +XkHyHu0VIeYp3nDwRA7S98837W4F6i1BnXA5f3EaE3rNGjsxK8zL2pvdCcDYbese +ETfba16HMzLXe1b4RSI3gwhlQ2MNKBwvskkQESf/Ew1DskBY0MCYFxo6hIp6LqMo +HAl5kvCwvuYL2jBdQhkKxU+Leu5Ei8Ie9XYNVy4yUeUAMnSUkVaEs/I8z+Mk8oYq +4QWqOc66XLcI13coDoxmv54kye3RjqdmZI8mg/3LCFotwceDuXyD43/vVhoTPEnp +CqXafV2pw4y95skMHmktI2qvSahaM4P6GGXl8HqmP3b+8V5mxMhNtVnuUha2kouw +DLNFUTg1cCLahM5SRolyA/XTGh7JOkJMYWPeJwN7l3K+lBtHHfj6DHtKEjUcyZFd ++Z55pDoAERumB6+BCnt6X2/0kEDV219RmsgxkGTWdFs+M7Y6EYYRtlinH4nqL6UD +eHWitYIatAHOvdHeNrbXN9L5P3tsUB4HzFa46WWtKqRtbCVTuPVZdw== +-----END RSA PRIVATE KEY----- + +b. end entity certificate and key + (SHA1withRSA 1024, subca_cert_sha1_512_1024.pem signed) +-----BEGIN CERTIFICATE----- +MIIB9jCCAaCgAwIBAgIBAzANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx +NTBaFw0yOTA0MjMwMTExNTBaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt +cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt +vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v +z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6 +c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07 +OorBleV92TAfBgNVHSMEGDAWgBQ3QIeJNg+2PK+k/ZrrLqaGxnpTjTANBgkqhkiG +9w0BAQUFAANBADV6X+ea0ftEKXy7yKNAbdIp35893T6AVwbdclomPkeOs86OtoTG +1BIzWSK9QE7W6Wbf63e2RdcqoLK+DxsuwUg= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,1FE5A37B770AF83D + +042bWtt4q0cB8pRuPUlMVncTP/WAz+mmPw3jXI3LFOBZeK6zFEDpI5M9c2JO+rqp +Za5UkYuIg69V7LngriqRynkRGGQp3xASMLr5NVbKHTE/Ol/iIuxKaCkumZmGXB/z +8bxQF5XN4tbKT4s3sWWmmKMicg6MHvySi3QVRG11PHRu/q7CEFPzJKRQ3fpaNcKD +NTBI5F6GP9ENa/eog4WGENjXS0v4Wa3IfaOhjKXrSxjLUqLH0C8g5WWg5IrXXtuI +pgyJ2kkE3Y/ChU7p7R42we6tBZqF5SiL5kFDn86DmHgCslTiZkIoE5i644sp03Sd +XkHyHu0VIeYp3nDwRA7S98837W4F6i1BnXA5f3EaE3rNGjsxK8zL2pvdCcDYbese +ETfba16HMzLXe1b4RSI3gwhlQ2MNKBwvskkQESf/Ew1DskBY0MCYFxo6hIp6LqMo +HAl5kvCwvuYL2jBdQhkKxU+Leu5Ei8Ie9XYNVy4yUeUAMnSUkVaEs/I8z+Mk8oYq +4QWqOc66XLcI13coDoxmv54kye3RjqdmZI8mg/3LCFotwceDuXyD43/vVhoTPEnp +CqXafV2pw4y95skMHmktI2qvSahaM4P6GGXl8HqmP3b+8V5mxMhNtVnuUha2kouw +DLNFUTg1cCLahM5SRolyA/XTGh7JOkJMYWPeJwN7l3K+lBtHHfj6DHtKEjUcyZFd ++Z55pDoAERumB6+BCnt6X2/0kEDV219RmsgxkGTWdFs+M7Y6EYYRtlinH4nqL6UD +eHWitYIatAHOvdHeNrbXN9L5P3tsUB4HzFa46WWtKqRtbCVTuPVZdw== +-----END RSA PRIVATE KEY----- + +c. end entity certificate and key + (SHA1withRSA 512, subca_cert_sha1_1024_1024.pem signed) +-----BEGIN CERTIFICATE----- +MIIB8zCCAVygAwIBAgIBBDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx +NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt +cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTBcMA0GCSqGSIb3 +DQEBAQUAA0sAMEgCQQCpfQzhld7w2JhW/aRaLkmrLrc/QAsQE+J4DXioXaajsWPo +uMmYmuiQolb6OIY/LcivSubKM3G5PkAWoovUPIWLAgMBAAGjTzBNMAsGA1UdDwQE +AwID6DAdBgNVHQ4EFgQUFWuXLkf4Ji57H9ISycgWi982TUIwHwYDVR0jBBgwFoAU +31g/ZkU6aXFAJVKhrrv0ebfAgeYwDQYJKoZIhvcNAQEFBQADgYEAUyW8PrEdbzLu +B+h6UemBOJ024rYq90hJE/5wUEKPvxZ9vPEUgl+io6cGhL3cLfxfh6z5xtEGp4Tb +NB0Ye3Qi01FBiNDY8s3rQRrmel6VysU8u+0Oi2jmQY6vZXn/zXN5rrTLITCaSicG +dOMv1xLM83Ee432WWlDwKOUxhzDGpWc= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,153918982D82A26E + +5w5MNd16M1draSfIFAuWNfP3869l9y8vMI1kOcxqsxjeG6YfgKUyu6PEYlj1R7d1 +/+UwVs9RGm3V7AwV4G1Qpnd+jaMLpgPVMP12sHPnslBE4SQe9bAZ+X5i2/5uesHv +bF7OBMqsYW8+Kgsy1Ac0pBx/8yoFYdD3KYFnIP20kV2Xxy4PtQQ6tHJ33dGslTNU +qrcJsyUyYj6wORlb7huuP5Ua8f28Xs/KvnNJG0094kC1WHi3Raf4AoD/rvraVtCQ +5jrK9se8D6su+S3SEW0YndxivbNx3xJu2O72e7lS6yb5ht3U7xNSSWTffIlW1okI +zjscK0iv9S+x452mLIFUgkmriVJLFfjTMRCbhS1J6q9FXLDdre/2O18FO2TvwRIE +6Bwt2utfOAGccRHLsdgcXkv+ngCTCkuCnmh2XZWqmvA= +-----END RSA PRIVATE KEY----- + +d. end entity certificate and key + (SHA1withRSA 512, subca_cert_sha1_512_1024.pem signed) +-----BEGIN CERTIFICATE----- +MIIBsjCCAVygAwIBAgIBBTANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx +NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt +cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTBcMA0GCSqGSIb3 +DQEBAQUAA0sAMEgCQQCpfQzhld7w2JhW/aRaLkmrLrc/QAsQE+J4DXioXaajsWPo +uMmYmuiQolb6OIY/LcivSubKM3G5PkAWoovUPIWLAgMBAAGjTzBNMAsGA1UdDwQE +AwID6DAdBgNVHQ4EFgQUFWuXLkf4Ji57H9ISycgWi982TUIwHwYDVR0jBBgwFoAU +N0CHiTYPtjyvpP2a6y6mhsZ6U40wDQYJKoZIhvcNAQEFBQADQQBG4grtrVEHick0 +z/6Lcl/MGyHT0c8KTXE0AMVXG1NRjAicAmYno/yDaJ9OmfymObKZKV9fF7yCW/N/ +TMU6m7N0 +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,153918982D82A26E + +5w5MNd16M1draSfIFAuWNfP3869l9y8vMI1kOcxqsxjeG6YfgKUyu6PEYlj1R7d1 +/+UwVs9RGm3V7AwV4G1Qpnd+jaMLpgPVMP12sHPnslBE4SQe9bAZ+X5i2/5uesHv +bF7OBMqsYW8+Kgsy1Ac0pBx/8yoFYdD3KYFnIP20kV2Xxy4PtQQ6tHJ33dGslTNU +qrcJsyUyYj6wORlb7huuP5Ua8f28Xs/KvnNJG0094kC1WHi3Raf4AoD/rvraVtCQ +5jrK9se8D6su+S3SEW0YndxivbNx3xJu2O72e7lS6yb5ht3U7xNSSWTffIlW1okI +zjscK0iv9S+x452mLIFUgkmriVJLFfjTMRCbhS1J6q9FXLDdre/2O18FO2TvwRIE +6Bwt2utfOAGccRHLsdgcXkv+ngCTCkuCnmh2XZWqmvA= +-----END RSA PRIVATE KEY----- + +e. end entity certificate and key + (MD2withRSA 1024, subca_cert_sha1_1024_1024.pem signed) +-----BEGIN CERTIFICATE----- +MIICNzCCAaCgAwIBAgIBBjANBgkqhkiG9w0BAQIFADAxMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx +NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt +cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt +vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v +z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6 +c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07 +OorBleV92TAfBgNVHSMEGDAWgBTfWD9mRTppcUAlUqGuu/R5t8CB5jANBgkqhkiG +9w0BAQIFAAOBgQBxKsFf8NNQcXjDoKJJSG4Rk6ikcrhiGYuUI32+XHvs6hnav1Zc +aJUpy7J4gMj/MnysMh/4AF9+m6zEEjuisXKUbYZhgtJxz+ukGSo163mJ8QJiAlRb +Iwsy81r08mlSCR6jx2YhDAUxJIPC92R5Vb4CEutB7tWTwwz7vIHq330erA== +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,1FE5A37B770AF83D + +042bWtt4q0cB8pRuPUlMVncTP/WAz+mmPw3jXI3LFOBZeK6zFEDpI5M9c2JO+rqp +Za5UkYuIg69V7LngriqRynkRGGQp3xASMLr5NVbKHTE/Ol/iIuxKaCkumZmGXB/z +8bxQF5XN4tbKT4s3sWWmmKMicg6MHvySi3QVRG11PHRu/q7CEFPzJKRQ3fpaNcKD +NTBI5F6GP9ENa/eog4WGENjXS0v4Wa3IfaOhjKXrSxjLUqLH0C8g5WWg5IrXXtuI +pgyJ2kkE3Y/ChU7p7R42we6tBZqF5SiL5kFDn86DmHgCslTiZkIoE5i644sp03Sd +XkHyHu0VIeYp3nDwRA7S98837W4F6i1BnXA5f3EaE3rNGjsxK8zL2pvdCcDYbese +ETfba16HMzLXe1b4RSI3gwhlQ2MNKBwvskkQESf/Ew1DskBY0MCYFxo6hIp6LqMo +HAl5kvCwvuYL2jBdQhkKxU+Leu5Ei8Ie9XYNVy4yUeUAMnSUkVaEs/I8z+Mk8oYq +4QWqOc66XLcI13coDoxmv54kye3RjqdmZI8mg/3LCFotwceDuXyD43/vVhoTPEnp +CqXafV2pw4y95skMHmktI2qvSahaM4P6GGXl8HqmP3b+8V5mxMhNtVnuUha2kouw +DLNFUTg1cCLahM5SRolyA/XTGh7JOkJMYWPeJwN7l3K+lBtHHfj6DHtKEjUcyZFd ++Z55pDoAERumB6+BCnt6X2/0kEDV219RmsgxkGTWdFs+M7Y6EYYRtlinH4nqL6UD +eHWitYIatAHOvdHeNrbXN9L5P3tsUB4HzFa46WWtKqRtbCVTuPVZdw== +-----END RSA PRIVATE KEY----- + +f. end entity certificate and key + (MD2withRSA 1024, subca_cert_sha1_512_1024.pem signed) +-----BEGIN CERTIFICATE----- +MIIB9jCCAaCgAwIBAgIBBzANBgkqhkiG9w0BAQIFADAxMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA4MDYwMTEx +NTFaFw0yOTA0MjMwMTExNTFaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt +cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAy6/2g3rxQzJEvTyOnBcEnZthmAD0AnP6LG8b35jt +vh71LHbF1FhkOT42Rfg20aBfWTMRf+FeOJBXpD4gCNjQA40vy8FaQxgYNAf7ho5v +z6yAEE6SG7YviE+XGcvpQo47w8c6QSQjpBzdw7JxwbVlzUT7pF8x3RnXlGhWnWv6 +c1ECAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSaXXERsow2Wm/6uT07 +OorBleV92TAfBgNVHSMEGDAWgBQ3QIeJNg+2PK+k/ZrrLqaGxnpTjTANBgkqhkiG +9w0BAQIFAANBAIX63Ypi9P71RnC/pcMbhD+wekRFsTzU593X3MC7tyBJtEXwvAZG +iMxXF5A+ohlr7/CrkV7ZTL8PLxnJdY5Y8rQ= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,1FE5A37B770AF83D + +042bWtt4q0cB8pRuPUlMVncTP/WAz+mmPw3jXI3LFOBZeK6zFEDpI5M9c2JO+rqp +Za5UkYuIg69V7LngriqRynkRGGQp3xASMLr5NVbKHTE/Ol/iIuxKaCkumZmGXB/z +8bxQF5XN4tbKT4s3sWWmmKMicg6MHvySi3QVRG11PHRu/q7CEFPzJKRQ3fpaNcKD +NTBI5F6GP9ENa/eog4WGENjXS0v4Wa3IfaOhjKXrSxjLUqLH0C8g5WWg5IrXXtuI +pgyJ2kkE3Y/ChU7p7R42we6tBZqF5SiL5kFDn86DmHgCslTiZkIoE5i644sp03Sd +XkHyHu0VIeYp3nDwRA7S98837W4F6i1BnXA5f3EaE3rNGjsxK8zL2pvdCcDYbese +ETfba16HMzLXe1b4RSI3gwhlQ2MNKBwvskkQESf/Ew1DskBY0MCYFxo6hIp6LqMo +HAl5kvCwvuYL2jBdQhkKxU+Leu5Ei8Ie9XYNVy4yUeUAMnSUkVaEs/I8z+Mk8oYq +4QWqOc66XLcI13coDoxmv54kye3RjqdmZI8mg/3LCFotwceDuXyD43/vVhoTPEnp +CqXafV2pw4y95skMHmktI2qvSahaM4P6GGXl8HqmP3b+8V5mxMhNtVnuUha2kouw +DLNFUTg1cCLahM5SRolyA/XTGh7JOkJMYWPeJwN7l3K+lBtHHfj6DHtKEjUcyZFd ++Z55pDoAERumB6+BCnt6X2/0kEDV219RmsgxkGTWdFs+M7Y6EYYRtlinH4nqL6UD +eHWitYIatAHOvdHeNrbXN9L5P3tsUB4HzFa46WWtKqRtbCVTuPVZdw== +-----END RSA PRIVATE KEY----- + +h. root CRL issuer +-----BEGIN CERTIFICATE----- +MIICKzCCAZSgAwIBAgIBCjANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDgxNjMwNTdaFw0yOTA0MjUxNjMwNTda +MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCy6RoQ6nMdeGJ6ijfjqDu3tDmeGLgnvfBcUKvcsvz9Ji3m +oGnTzECo1oLV+A4/TJxOlak+ZiQ5KVyvfMcXLJeT6dRpXQZ+uc6TT3SkBq94VFzX +qkk08z42JNdk1s5uyW8nRfg7+xntajQVrysoPYNDhu21cPnjDkRiBsIdS7+75QID +AQABo3cwdTAdBgNVHQ4EFgQUGcJU6xWo66kI1QBvlfTQKxxmx9IwRwYDVR0jBEAw +PoAU59AvsZmWPwU2m+FvYAad3Rmu1oKhI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD +VQQKEwdFeGFtcGxlggEAMAsGA1UdDwQEAwIBAjANBgkqhkiG9w0BAQQFAAOBgQBx +uKL59VInPdCi+8JL4B+S5YjlPL4ZOBHTjS0JlNxtjbGZdfs+3E9PUAdqhMJO4vq7 +XD+hGtgZtwSqGaSUYAtpLdoCr7vvPkcrxYTG2Ak+UiTbZhmJeSswKgFaCmjjdMCy +y64UP2DQfn6Zi0wCfeao0m9s3zRLuJpgaQGiSHTQKA== +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,41E4237825CE0148 + +9nbfd7dsaS+fkFYrU1+wTcevjdRLF/j9DUVQh/2bsFlVEYgeL8A+XpvpbXHYBd7H +oBreofDNseibHe4EgISGPK8RymjYutQqPpbHwXd25jlUuUapvvuCj8V6qnhgpqEo +zXL1Nd2c6KZgdySosyWy8JfIBZJ3kwiSkXVwzs8R4bAGrg1VS80GuszvCv8Fzjoc +LuesX6fViE9yFzLsyOvn/W12DKhTXwiXTQYLUupM8zI9Kpozbea52ZIPMJ9HEiaY +JgwNj05w33VxTe/tq3R9vS2Ee6aM4odi6CQEheLsUAnyE0BTsITKzwwTI25WTv25 +W+gwSF3V49a34MojTdlORq5iH0b3rYl7OMdk+99elJSkyQIbVwwOCFrKuSXYXvV7 +s9iMPFUbi+bZ3oP6zM5kVUcH6KyVeYfkuLf2+k1vPlav8/W5v+WfnvUNOBx76Ira +BzVPYmm2V+YFiFL1hugm5Wv+yyx8QcfgXbvhNHoIEj7hh6Ac48FhtqEcBHjuT/gy +7atJJUdOH6hhmD34hkHGnhcDE15ZOczxTLRC9450h5HKsZ0FILRlCBZLmiedycs2 +zqhUpR4jzDG9jKrlDU4ErfMgPLjveZc3/VT3bc+TYfuC8szCaQ5XX1JVcabZ+HQw +pwmA1ONZDVsFzwbJy9+5bgXX+wLD5kaez8EHNDS5PgqgL0UdrWjdRi6e1RwlTDEw +g/d7TZm/iQeL1iUIfkPA1f0ByYIiyd3XQqiQ/Mf1C16lQkhTHDwofFJdL8otT2Ha +dk6fa7lBOnrpbRKUdpJpYfyqHg80BYNPu6BacVXlYqtJtkFK04qHbA== +-----END RSA PRIVATE KEY----- + +i. CRL issued by root CRL issuer +-----BEGIN X509 CRL----- +MIH2MGECAQEwDQYJKoZIhvcNAQEFBQAwHzELMAkGA1UEBhMCVVMxEDAOBgNVBAoT +B0V4YW1wbGUXDTA5MDgwODE2MzU1MFoXDTI4MTAwNzE2MzU1MFqgDjAMMAoGA1Ud +FAQDAgEAMA0GCSqGSIb3DQEBBQUAA4GBAJCd7e25MruuWJP/KmenGC6CR22pQuG+ +XhRaAtpHkNRls8+TfBxm2PtRrXCAcDb68kNLdwvlAlCUwmL6HOx4VB3r+8QRUlDa +T48wVp1ojGU2b2XbPtXiYZBXW6hBsFHGDJM/IAGJPE2PbVYGlBc23A9V9WyPyThi +9XXG1iOTIJ6u +-----END X509 CRL----- + +j. subca CRL issuer +-----BEGIN CERTIFICATE----- +MIICPTCCAaagAwIBAgIBCzANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA4MDgxNjMwNThaFw0yOTA0MjUxNjMwNTha +MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz +cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8KICP0bdOZVlR9gZu7TgD +znXgSMER1IQtompgr1mWeZjX4LmRck3/ogHoxwC4RbNPKI3KIihcVdFHw2jgvE0M +mpf2lI50tmhnLitM8P0/q8xUU/KncipADo4hkM5TbpjPeGUBTGLKzGrq7yyT9Uli +Z74rrp1mS59TxcEI2YQMIQIDAQABo3cwdTAdBgNVHQ4EFgQUDGgpD4L8V3aBJPLx +C7diZ0M0wWMwRwYDVR0jBEAwPoAU59AvsZmWPwU2m+FvYAad3Rmu1oKhI6QhMB8x +CzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlggEAMAsGA1UdDwQEAwIBAjAN +BgkqhkiG9w0BAQQFAAOBgQCcXqRge5UuW0duf/XnUWP4hrm4Q9EHJaiHZDYxI+WW +Ca3OXdsrpgGi+RSgeMtQzlZ7YAwyYVV91U4BnX6s/97Vp5xbR3wr8Qbx67inM8Lp +Tuo+e0nyTxwlwi9cSyy5MfJ8jfzaD+n8akhV+sx0Mmiv77YlrShP24lod55gJHKC +vQ== +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,16EC4E2C0855BD5C + +dJHcUsnACMhfESAalWrWrfARnUgGhpp3vupjePUiBJ86YmKaNNr6GAwDukg3EJvs +tboO1QQziLSf9pP7gw82Vp5YctEkk7vJVvCcq3QkZAsjNUHf3m3ne2qg8HngufzY +IS/C3EtKuMr3oqa7P8wvMcsBs1G1ga/YqCWoKzowXhybaYPe20fwUNRtgqgdS5Gy +bAzQB9R+Ua2tCaXb3CBYnrczsYFPhjuULr4qbWgHVBWhnkS3OIz71WqcCoXmvD3s +bsjoZRCJUM6Zavyzs0kVGZogiPdr+KUyzjNNsnxle5cEET6nqkYR16UT/Fvemz9Q +szh/y0gCi1nZb6cw5e9BJyF1GlobzxWyMwwY9L4vZNaBNaVRun+6dRWy0svaPuEy +fV/9Y0/la9scyA5yNHz8xud3Njhj2ghyG5Nqbs3N/pPXRVdh7WNFBnc+L/SIBhhB +/Ha9+OZdqyuMf3G+I1+WVADQr8xQP8/yLEvybZYtssjnuCmQSLPDDQFnp2Z3spax ++AT+T4dRimMjf0mZK/NlRJU9PWqMHzsJGBY1A903oAiiHiRFD10z8vyPBigSDF2W +ct6a8WI1prKho6HbMqeIlSPk+HkdCGZedNNbvRlKl4Y56IsHGAhb3wvQ+94049P9 +wu5thK69jNb7ie3YEefAZTb5kD0h+oB8BILOJ5B29C04JdDe6P6hjGKD7x3nRhHM +nyCUMB/fhYpoXdDhz8CeJ77hFt2zFZRstlDctQsDqLkC0AdvlOFsEFqGM4AkBGcV +f6Y+ykNQB3vEWPZsWqVXHB2vQvk00R55tgu+R5JJ45NLG2TqyOp/4A== +-----END RSA PRIVATE KEY----- + +k. CRL issued by subca CRL issuer +-----BEGIN X509 CRL----- +MIIBLTCBlwIBATANBgkqhkiG9w0BAQIFADAxMQswCQYDVQQGEwJVUzEQMA4GA1UE +ChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMRcNMDkwODA4MTYzNTUxWhcNMjgx +MDA3MTYzNTUxWjAiMCACAQIXDTA5MDgwODE2MzU1MFowDDAKBgNVHRUEAwoBBKAO +MAwwCgYDVR0UBAMCAQAwDQYJKoZIhvcNAQECBQADgYEAbIs7ws4/M24NYrIO0XY6 +UVxni0ZoQa+1R7NwU6unr4jFEVD+W/b+JEMfm0RUmpSa7HrUYsw+NycD3m5CD6VJ +U4iuGGeJvHdrYJiPIYkEiFQnhAGOj8oS/nWtPvDKbuBMZI9atKkypby9At8h9URq +1g/KSIM3rd1PYADdcPsok4I= +-----END X509 CRL----- + diff --git a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/generate.sh b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/generate.sh new file mode 100644 index 00000000000..ff936e5d1f0 --- /dev/null +++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/generate.sh @@ -0,0 +1,255 @@ +# +# Copyright 2009 Sun Microsystems, 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. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +#!/bin/ksh +# +# needs ksh to run the script. +set -e + +OPENSSL=openssl + +# generate a self-signed root certificate +if [ ! -f root/finished ]; then + if [ ! -d root ]; then + mkdir root + fi + + # SHA1withRSA 1024 + ${OPENSSL} req -x509 -newkey rsa:1024 -keyout root/root_key_1024.pem \ + -out root/root_cert_sha1_1024.pem -subj "/C=US/O=Example" \ + -config openssl.cnf -reqexts cert_issuer -days 7650 -sha1 \ + -passin pass:passphrase -passout pass:passphrase + + # SHA1withRSA 512 + ${OPENSSL} req -x509 -newkey rsa:512 -keyout root/root_key_512.pem \ + -out root/root_cert_sha1_512.pem -subj "/C=US/O=Example" \ + -config openssl.cnf -reqexts cert_issuer -days 7650 -sha1 \ + -passin pass:passphrase -passout pass:passphrase + + # MD2withRSA 2048 + ${OPENSSL} req -x509 -newkey rsa:2048 -keyout root/root_key_2048.pem \ + -out root/root_cert_md2_2048.pem -subj "/C=US/O=Example" \ + -config openssl.cnf -reqexts cert_issuer -days 7650 -md2 \ + -passin pass:passphrase -passout pass:passphrase + + openssl req -newkey rsa:1024 -keyout root/root_crlissuer_key.pem \ + -out root/root_crlissuer_req.pem -subj "/C=US/O=Example" -days 7650 \ + -passin pass:passphrase -passout pass:passphrase + + openssl x509 -req -in root/root_crlissuer_req.pem -extfile openssl.cnf \ + -extensions crl_issuer -CA root/root_cert_sha1_1024.pem \ + -CAkey root/root_key_1024.pem -out root/root_crlissuer_cert.pem \ + -CAcreateserial -CAserial root/root_cert.srl -days 7200 \ + -passin pass:passphrase + + touch root/finished +fi + + +# generate subca cert issuer +if [ ! -f subca/finished ]; then + if [ ! -d subca ]; then + mkdir subca + fi + + # RSA 1024 + ${OPENSSL} req -newkey rsa:1024 -keyout subca/subca_key_1024.pem \ + -out subca/subca_req_1024.pem -subj "/C=US/O=Example/OU=Class-1" \ + -days 7650 -passin pass:passphrase -passout pass:passphrase + + # RSA 512 + ${OPENSSL} req -newkey rsa:512 -keyout subca/subca_key_512.pem \ + -out subca/subca_req_512.pem -subj "/C=US/O=Example/OU=Class-1" \ + -days 7650 -passin pass:passphrase -passout pass:passphrase + + # SHA1withRSA 1024 signed with RSA 1024 + ${OPENSSL} x509 -req -in subca/subca_req_1024.pem -extfile openssl.cnf \ + -extensions cert_issuer -CA root/root_cert_sha1_1024.pem \ + -CAkey root/root_key_1024.pem -out subca/subca_cert_sha1_1024_1024.pem \ + -CAcreateserial -sha1 \ + -CAserial root/root_cert.srl -days 7200 -passin pass:passphrase + + # SHA1withRSA 1024 signed with RSA 512 + ${OPENSSL} x509 -req -in subca/subca_req_1024.pem -extfile openssl.cnf \ + -extensions cert_issuer -CA root/root_cert_sha1_512.pem \ + -CAkey root/root_key_512.pem -out subca/subca_cert_sha1_1024_512.pem \ + -CAcreateserial -sha1 \ + -CAserial root/root_cert.srl -days 7200 -passin pass:passphrase + + # SHA1withRSA 512 signed with RSA 1024 + ${OPENSSL} x509 -req -in subca/subca_req_512.pem -extfile openssl.cnf \ + -extensions cert_issuer -CA root/root_cert_sha1_1024.pem \ + -CAkey root/root_key_1024.pem -out subca/subca_cert_sha1_512_1024.pem \ + -CAcreateserial -sha1 \ + -CAserial root/root_cert.srl -days 7200 -passin pass:passphrase + + # SHA1withRSA 512 signed with RSA 512 + ${OPENSSL} x509 -req -in subca/subca_req_512.pem -extfile openssl.cnf \ + -extensions cert_issuer -CA root/root_cert_sha1_512.pem \ + -CAkey root/root_key_512.pem -out subca/subca_cert_sha1_512_512.pem \ + -CAcreateserial -sha1 \ + -CAserial root/root_cert.srl -days 7200 -passin pass:passphrase + + # MD2withRSA 1024 signed with RSA 1024 + ${OPENSSL} x509 -req -in subca/subca_req_1024.pem -extfile openssl.cnf \ + -extensions cert_issuer -CA root/root_cert_sha1_1024.pem \ + -CAkey root/root_key_1024.pem -out subca/subca_cert_md2_1024_1024.pem \ + -CAcreateserial -md2 \ + -CAserial root/root_cert.srl -days 7200 -passin pass:passphrase + + # MD2withRSA 1024 signed with RSA 512 + ${OPENSSL} x509 -req -in subca/subca_req_1024.pem -extfile openssl.cnf \ + -extensions cert_issuer -CA root/root_cert_sha1_512.pem \ + -CAkey root/root_key_512.pem -out subca/subca_cert_md2_1024_512.pem \ + -CAcreateserial -md2 \ + -CAserial root/root_cert.srl -days 7200 -passin pass:passphrase + + openssl req -newkey rsa:1024 -keyout subca/subca_crlissuer_key.pem \ + -out subca/subca_crlissuer_req.pem -subj "/C=US/O=Example/OU=Class-1" \ + -days 7650 -passin pass:passphrase -passout pass:passphrase + + openssl x509 -req -in subca/subca_crlissuer_req.pem -extfile openssl.cnf \ + -extensions crl_issuer -CA root/root_cert_sha1_1024.pem \ + -CAkey root/root_key_1024.pem -out subca/subca_crlissuer_cert.pem \ + -CAcreateserial -CAserial root/root_cert.srl -days 7200 \ + -passin pass:passphrase + + touch subca/finished +fi + + +# generate certifiacte for Alice +if [ ! -f subca/alice/finished ]; then + if [ ! -d subca/alice ]; then + mkdir -p subca/alice + fi + + # RSA 1024 + ${OPENSSL} req -newkey rsa:1024 -keyout subca/alice/alice_key_1024.pem \ + -out subca/alice/alice_req_1024.pem \ + -subj "/C=US/O=Example/OU=Class-1/CN=Alice" -days 7650 \ + -passin pass:passphrase -passout pass:passphrase + + # RSA 512 + ${OPENSSL} req -newkey rsa:512 -keyout subca/alice/alice_key_512.pem \ + -out subca/alice/alice_req_512.pem \ + -subj "/C=US/O=Example/OU=Class-1/CN=Alice" -days 7650 \ + -passin pass:passphrase -passout pass:passphrase + + # SHA1withRSA 1024 signed with RSA 1024 + ${OPENSSL} x509 -req -in subca/alice/alice_req_1024.pem \ + -extfile openssl.cnf -extensions ee_of_subca \ + -CA subca/subca_cert_sha1_1024_1024.pem \ + -CAkey subca/subca_key_1024.pem \ + -out subca/alice/alice_cert_sha1_1024_1024.pem -CAcreateserial -sha1 \ + -CAserial subca/subca_cert.srl -days 7200 -passin pass:passphrase + + # SHA1withRSA 1024 signed with RSA 512 + ${OPENSSL} x509 -req -in subca/alice/alice_req_1024.pem \ + -extfile openssl.cnf -extensions ee_of_subca \ + -CA subca/subca_cert_sha1_512_1024.pem \ + -CAkey subca/subca_key_512.pem \ + -out subca/alice/alice_cert_sha1_1024_512.pem -CAcreateserial -sha1 \ + -CAserial subca/subca_cert.srl -days 7200 -passin pass:passphrase + + # SHA1withRSA 512 signed with RSA 1024 + ${OPENSSL} x509 -req -in subca/alice/alice_req_512.pem \ + -extfile openssl.cnf -extensions ee_of_subca \ + -CA subca/subca_cert_sha1_1024_1024.pem \ + -CAkey subca/subca_key_1024.pem \ + -out subca/alice/alice_cert_sha1_512_1024.pem -CAcreateserial -sha1 \ + -CAserial subca/subca_cert.srl -days 7200 -passin pass:passphrase + + # SHA1withRSA 512 signed with RSA 512 + ${OPENSSL} x509 -req -in subca/alice/alice_req_512.pem \ + -extfile openssl.cnf -extensions ee_of_subca \ + -CA subca/subca_cert_sha1_512_1024.pem \ + -CAkey subca/subca_key_512.pem \ + -out subca/alice/alice_cert_sha1_512_512.pem -CAcreateserial -sha1 \ + -CAserial subca/subca_cert.srl -days 7200 -passin pass:passphrase + + # MD2withRSA 1024 signed with RSA 1024 + ${OPENSSL} x509 -req -in subca/alice/alice_req_1024.pem \ + -extfile openssl.cnf -extensions ee_of_subca \ + -CA subca/subca_cert_sha1_1024_1024.pem \ + -CAkey subca/subca_key_1024.pem \ + -out subca/alice/alice_cert_md2_1024_1024.pem -CAcreateserial -md2 \ + -CAserial subca/subca_cert.srl -days 7200 -passin pass:passphrase + + # MD2withRSA 1024 signed with RSA 512 + ${OPENSSL} x509 -req -in subca/alice/alice_req_1024.pem \ + -extfile openssl.cnf -extensions ee_of_subca \ + -CA subca/subca_cert_sha1_512_1024.pem \ + -CAkey subca/subca_key_512.pem \ + -out subca/alice/alice_cert_md2_1024_512.pem -CAcreateserial -md2 \ + -CAserial subca/subca_cert.srl -days 7200 -passin pass:passphrase + + touch subca/alice/finished +fi + +if [ ! -f root/revoked ]; then + if [ ! -d root ]; then + mkdir root + fi + + if [ ! -f root/index.txt ]; then + touch root/index.txt + echo 00 > root/crlnumber + fi + + openssl ca -gencrl -config openssl.cnf -name ca_top -crldays 7000 -md sha1 \ + -crl_reason superseded -keyfile root/root_crlissuer_key.pem \ + -cert root/root_crlissuer_cert.pem -out root/top_crl.pem \ + -passin pass:passphrase + + touch root/revoked +fi + +if [ ! -f subca/revoked ]; then + if [ ! -d subca ]; then + mkdir subca + fi + + if [ ! -f subca/index.txt ]; then + touch subca/index.txt + echo 00 > subca/crlnumber + fi + + # revoke alice's SHA1withRSA 1024 signed with RSA 1024 + openssl ca -revoke subca/alice/alice_cert_sha1_1024_1024.pem \ + -config openssl.cnf \ + -name ca_subca -crl_reason superseded \ + -keyfile subca/subca_crlissuer_key.pem \ + -cert subca/subca_crlissuer_cert.pem -passin pass:passphrase + + openssl ca -gencrl -config openssl.cnf \ + -name ca_subca -crldays 7000 -md md2 \ + -crl_reason superseded -keyfile subca/subca_crlissuer_key.pem \ + -cert subca/subca_crlissuer_cert.pem \ + -out subca/subca_crl.pem \ + -passin pass:passphrase + + touch subca/revoked +fi diff --git a/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/openssl.cnf b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/openssl.cnf new file mode 100644 index 00000000000..5a090f05f3a --- /dev/null +++ b/jdk/test/sun/security/provider/certpath/DisabledAlgorithms/openssl.cnf @@ -0,0 +1,206 @@ +# +# Copyright 2009 Sun Microsystems, 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. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +# +# OpenSSL configuration file. +# + +HOME = . +RANDFILE = $ENV::HOME/.rnd + +[ ca ] +default_ca = CA_default + +[ CA_default ] +dir = ./top +certs = $dir/certs +crl_dir = $dir/crl +database = $dir/index.txt +unique_subject = no +new_certs_dir = $dir/newcerts +certificate = $dir/cacert.pem +serial = $dir/serial +crlnumber = $dir/crlnumber +crl = $dir/crl.pem +private_key = $dir/private/cakey.pem +RANDFILE = $dir/private/.rand +x509_extensions = v3_ca + +name_opt = ca_default +cert_opt = ca_default + +default_days = 7650 +default_crl_days = 30 +default_md = sha1 +preserve = no + +policy = policy_anything + +[ ca_top ] +dir = ./root +certs = $dir/certs +crl_dir = $dir/crl +database = $dir/index.txt +unique_subject = no +new_certs_dir = $dir/newcerts +certificate = $dir/cacert.pem +serial = $dir/serial +crlnumber = $dir/crlnumber +crl = $dir/crl.pem +private_key = $dir/private/cakey.pem +RANDFILE = $dir/private/.rand + +x509_extensions = v3_ca + +name_opt = ca_default +cert_opt = ca_default + +default_days = 7650 +default_crl_days = 30 +default_md = sha1 +preserve = no + +policy = policy_anything + +[ ca_subca ] +dir = ./subca +certs = $dir/certs +crl_dir = $dir/crl +database = $dir/index.txt +unique_subject = no +new_certs_dir = $dir/newcerts + +certificate = $dir/cacert.pem +serial = $dir/serial +crlnumber = $dir/crlnumber +crl = $dir/crl.pem +private_key = $dir/private/cakey.pem +RANDFILE = $dir/private/.rand + +x509_extensions = usr_cert + +name_opt = ca_default +cert_opt = ca_default + +default_days = 7650 +default_crl_days = 30 +default_md = sha1 +preserve = no + +policy = policy_anything + +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ req ] +default_bits = 1024 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca + +string_mask = nombstr + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = NO +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = A-State + +localityName = Locality Name (eg, city) + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Internet Widgits Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) + +commonName = Common Name (eg, YOUR name) +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 64 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 +unstructuredName = An optional company name + + +[ usr_cert ] +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName = email:example@openjdk.net, RID:1.2.3.4:true + +[ v3_ca ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +basicConstraints = critical,CA:true +keyUsage = keyCertSign + +[ cert_issuer ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +basicConstraints = critical,CA:true +keyUsage = keyCertSign + + +[ crl_issuer ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +keyUsage = cRLSign + + +[ crl_ext ] +authorityKeyIdentifier = keyid:always,issuer:always + +[ ee_of_subca ] +keyUsage = nonRepudiation, digitalSignature, keyEncipherment, keyAgreement + +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer From 2513311062d2e3270eac4347ae3484730cdb86e0 Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Thu, 20 Aug 2009 12:46:43 +0400 Subject: [PATCH 003/172] 6664512: Component and [Default]KeyboardFocusManager pass security sensitive objects to loggers ToString is called on security sensitive objects Reviewed-by: art, hawtin --- jdk/src/share/classes/java/awt/Component.java | 2 +- .../java/awt/DefaultKeyboardFocusManager.java | 60 +++++++++++++------ .../java/awt/KeyboardFocusManager.java | 23 +++---- .../share/classes/sun/awt/DebugSettings.java | 2 +- .../classes/sun/awt/X11/XBaseWindow.java | 17 ++++-- .../sun/awt/X11/XCheckboxMenuItemPeer.java | 4 -- .../classes/sun/awt/X11/XComponentPeer.java | 22 +++++-- .../classes/sun/awt/X11/XContentWindow.java | 6 +- .../classes/sun/awt/X11/XDecoratedPeer.java | 53 +++++++++++----- .../sun/awt/X11/XDropTargetProtocol.java | 5 +- .../sun/awt/X11/XFocusProxyWindow.java | 1 - .../classes/sun/awt/X11/XFramePeer.java | 4 +- .../classes/sun/awt/X11/XIconWindow.java | 11 +++- .../classes/sun/awt/X11/XInputMethod.java | 5 +- .../classes/sun/awt/X11/XMenuItemPeer.java | 2 - .../classes/sun/awt/X11/XNETProtocol.java | 27 +++++++-- .../classes/sun/awt/X11/XProtocol.java | 6 +- .../classes/sun/awt/X11/XQueryTree.java | 1 - .../solaris/classes/sun/awt/X11/XToolkit.java | 19 ++++-- .../classes/sun/awt/X11/XTrayIconPeer.java | 43 ++++++++----- jdk/src/solaris/classes/sun/awt/X11/XWM.java | 48 +++++++++++---- .../solaris/classes/sun/awt/X11/XWindow.java | 30 +++++++--- .../classes/sun/awt/X11/XWindowPeer.java | 56 +++++++++++++---- .../sun/awt/windows/WMenuItemPeer.java | 2 +- .../classes/sun/awt/windows/WPanelPeer.java | 1 - 25 files changed, 317 insertions(+), 133 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index 91347ad1b18..3ecf30c51d5 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -4477,7 +4477,7 @@ public abstract class Component implements ImageObserver, MenuContainer, } if (eventLog.isLoggable(Level.FINEST)) { - eventLog.log(Level.FINEST, "{0}", e); + eventLog.log(Level.FINEST, "{0}", String.valueOf(e)); } /* diff --git a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java index 71342bdaeed..d7e5cba7ca4 100644 --- a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java +++ b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java @@ -380,7 +380,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { // should receive focus first if (focusLog.isLoggable(Level.FINER)) { focusLog.log(Level.FINER, "tempLost {0}, toFocus {1}", - new Object[]{tempLost, toFocus}); + new Object[]{String.valueOf(tempLost), String.valueOf(toFocus)}); } if (tempLost != null) { tempLost.requestFocusInWindow(CausedFocusEvent.Cause.ACTIVATION); @@ -448,7 +448,8 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { Component newFocusOwner = fe.getComponent(); if (oldFocusOwner == newFocusOwner) { if (focusLog.isLoggable(Level.FINE)) { - focusLog.log(Level.FINE, "Skipping {0} because focus owner is the same", new Object[] {e}); + focusLog.log(Level.FINE, "Skipping {0} because focus owner is the same", + new Object[] {String.valueOf(e)}); } // We can't just drop the event - there could be // type-ahead markers associated with it. @@ -565,16 +566,20 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { FocusEvent fe = (FocusEvent)e; Component currentFocusOwner = getGlobalFocusOwner(); if (currentFocusOwner == null) { - if (focusLog.isLoggable(Level.FINE)) focusLog.log(Level.FINE, "Skipping {0} because focus owner is null", - new Object[] {e}); + if (focusLog.isLoggable(Level.FINE)) { + focusLog.log(Level.FINE, "Skipping {0} because focus owner is null", + new Object[] {String.valueOf(e)}); + } break; } // Ignore cases where a Component loses focus to itself. // If we make a mistake because of retargeting, then the // FOCUS_GAINED handler will correct it. if (currentFocusOwner == fe.getOppositeComponent()) { - if (focusLog.isLoggable(Level.FINE)) focusLog.log(Level.FINE, "Skipping {0} because current focus owner is equal to opposite", - new Object[] {e}); + if (focusLog.isLoggable(Level.FINE)) { + focusLog.log(Level.FINE, "Skipping {0} because current focus owner is equal to opposite", + new Object[] {String.valueOf(e)}); + } break; } @@ -642,9 +647,11 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { Window losingFocusWindow = we.getWindow(); Window activeWindow = getGlobalActiveWindow(); Window oppositeWindow = we.getOppositeWindow(); - if (focusLog.isLoggable(Level.FINE)) focusLog.log(Level.FINE, "Active {0}, Current focused {1}, losing focus {2} opposite {3}", - new Object[] {activeWindow, currentFocusedWindow, - losingFocusWindow, oppositeWindow}); + if (focusLog.isLoggable(Level.FINE)) { + focusLog.log(Level.FINE, "Active {0}, Current focused {1}, losing focus {2} opposite {3}", + new Object[] {String.valueOf(activeWindow), String.valueOf(currentFocusedWindow), + String.valueOf(losingFocusWindow), String.valueOf(oppositeWindow)}); + } if (currentFocusedWindow == null) { break; } @@ -828,7 +835,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { } } if (ke != null) { - focusLog.log(Level.FINER, "Pumping approved event {0}", new Object[] {ke}); + if (focusLog.isLoggable(Level.FINER)) { + focusLog.log(Level.FINER, "Pumping approved event {0}", + new Object[] {String.valueOf(ke)}); + } enqueuedKeyEvents.removeFirst(); } } @@ -850,7 +860,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { Iterator iter = typeAheadMarkers.iterator(); while (iter.hasNext()) { TypeAheadMarker marker = (TypeAheadMarker)iter.next(); - focusLog.log(Level.FINEST, " {0}", marker); + focusLog.log(Level.FINEST, " {0}", String.valueOf(marker)); } } } @@ -878,7 +888,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { // The fix is rolled out. if (ke.getWhen() > marker.after) { - focusLog.log(Level.FINER, "Storing event {0} because of marker {1}", new Object[] {ke, marker}); + if (focusLog.isLoggable(Level.FINER)) { + focusLog.log(Level.FINER, "Storing event {0} because of marker {1}", + new Object[] {String.valueOf(ke), String.valueOf(marker)}); + } enqueuedKeyEvents.addLast(ke); return true; } @@ -890,7 +903,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { } case FocusEvent.FOCUS_GAINED: - focusLog.log(Level.FINEST, "Markers before FOCUS_GAINED on {0}", new Object[] {target}); + if (focusLog.isLoggable(Level.FINEST)) { + focusLog.log(Level.FINEST, "Markers before FOCUS_GAINED on {0}", + new Object[] {String.valueOf(target)}); + } dumpMarkers(); // Search the marker list for the first marker tied to // the Component which just gained focus. Then remove @@ -919,10 +935,14 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { } } else { // Exception condition - event without marker - focusLog.log(Level.FINER, "Event without marker {0}", e); + if (focusLog.isLoggable(Level.FINER)) { + focusLog.log(Level.FINER, "Event without marker {0}", String.valueOf(e)); + } } } + focusLog.log(Level.FINEST, "Markers after FOCUS_GAINED"); + dumpMarkers(); redispatchEvent(target, e); @@ -1159,8 +1179,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { return; } - focusLog.log(Level.FINER, "Enqueue at {0} for {1}", - new Object[] {after, untilFocused}); + if (focusLog.isLoggable(Level.FINER)) { + focusLog.log(Level.FINER, "Enqueue at {0} for {1}", + new Object[] {after, String.valueOf(untilFocused)}); + } int insertionIndex = 0, i = typeAheadMarkers.size(); @@ -1199,8 +1221,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { return; } - focusLog.log(Level.FINER, "Dequeue at {0} for {1}", - new Object[] {after, untilFocused}); + if (focusLog.isLoggable(Level.FINER)) { + focusLog.log(Level.FINER, "Dequeue at {0} for {1}", + new Object[] {after, String.valueOf(untilFocused)}); + } TypeAheadMarker marker; ListIterator iter = typeAheadMarkers.listIterator diff --git a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java index 521c70403ae..fd412d8646e 100644 --- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java @@ -611,7 +611,7 @@ public abstract class KeyboardFocusManager void setNativeFocusOwner(Component comp) { if (focusLog.isLoggable(Level.FINEST)) { focusLog.log(Level.FINEST, "Calling peer {0} setCurrentFocusOwner for {1}", - new Object[] {peer, comp}); + new Object[] {String.valueOf(peer), String.valueOf(comp)}); } peer.setCurrentFocusOwner(comp); } @@ -2363,20 +2363,20 @@ public abstract class KeyboardFocusManager Window nativeFocusedWindow = thisManager.getNativeFocusedWindow(); if (focusLog.isLoggable(Level.FINER)) { focusLog.log(Level.FINER, "SNFH for {0} in {1}", - new Object[] {descendant, heavyweight}); + new Object[] {String.valueOf(descendant), String.valueOf(heavyweight)}); } if (focusLog.isLoggable(Level.FINEST)) { focusLog.log(Level.FINEST, "0. Current focus owner {0}", - currentFocusOwner); + String.valueOf(currentFocusOwner)); focusLog.log(Level.FINEST, "0. Native focus owner {0}", - nativeFocusOwner); + String.valueOf(nativeFocusOwner)); focusLog.log(Level.FINEST, "0. Native focused window {0}", - nativeFocusedWindow); + String.valueOf(nativeFocusedWindow)); } synchronized (heavyweightRequests) { HeavyweightFocusRequest hwFocusRequest = getLastHWRequest(); if (focusLog.isLoggable(Level.FINEST)) { - focusLog.log(Level.FINEST, "Request {0}", hwFocusRequest); + focusLog.log(Level.FINEST, "Request {0}", String.valueOf(hwFocusRequest)); } if (hwFocusRequest == null && heavyweight == nativeFocusOwner) @@ -2385,7 +2385,7 @@ public abstract class KeyboardFocusManager // Redundant request. if (focusLog.isLoggable(Level.FINEST)) focusLog.log(Level.FINEST, "1. SNFH_FAILURE for {0}", - descendant); + String.valueOf(descendant)); return SNFH_FAILURE; } @@ -2418,7 +2418,7 @@ public abstract class KeyboardFocusManager SunToolkit.postEvent(descendant.appContext, newFocusOwnerEvent); if (focusLog.isLoggable(Level.FINEST)) - focusLog.log(Level.FINEST, "2. SNFH_HANDLED for {0}", descendant); + focusLog.log(Level.FINEST, "2. SNFH_HANDLED for {0}", String.valueOf(descendant)); return SNFH_SUCCESS_HANDLED; } else if (hwFocusRequest != null && hwFocusRequest.heavyweight == heavyweight) { @@ -2857,11 +2857,12 @@ public abstract class KeyboardFocusManager KeyboardFocusManager manager = getCurrentKeyboardFocusManager(); if (focusLog.isLoggable(Level.FINER)) { if (event instanceof FocusEvent || event instanceof WindowEvent) { - focusLog.log(Level.FINER, ">>> {0}", new Object[] {event}); + focusLog.log(Level.FINER, ">>> {0}", new Object[] {String.valueOf(event)}); } if (focusLog.isLoggable(Level.FINER) && event instanceof KeyEvent) { - focusLog.log(Level.FINER, " focus owner is {0}", new Object[] {manager.getGlobalFocusOwner()}); - focusLog.log(Level.FINER, ">>> {0}", new Object[] {event}); + focusLog.log(Level.FINER, " focus owner is {0}", + new Object[] {String.valueOf(manager.getGlobalFocusOwner())}); + focusLog.log(Level.FINER, ">>> {0}", new Object[] {String.valueOf(event)}); } } diff --git a/jdk/src/share/classes/sun/awt/DebugSettings.java b/jdk/src/share/classes/sun/awt/DebugSettings.java index 0d2aaaf6251..ac343ffac4a 100644 --- a/jdk/src/share/classes/sun/awt/DebugSettings.java +++ b/jdk/src/share/classes/sun/awt/DebugSettings.java @@ -129,7 +129,7 @@ final class DebugSettings { // echo the initial property settings to stdout if (log.isLoggable(Level.FINE)) { - log.log(Level.FINE, "DebugSettings:\n{0}", this); + log.log(Level.FINE, "DebugSettings:\n{0}", String.valueOf(this)); } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java index 095f36c5efd..3577b5f4e9f 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java @@ -824,7 +824,9 @@ public class XBaseWindow { * The active grab overrides activated automatic grab. */ public boolean grabInput() { - grabLog.log(Level.FINE, "Grab input on {0}", new Object[] {this}); + if (grabLog.isLoggable(Level.FINE)) { + grabLog.log(Level.FINE, "Grab input on {0}", new Object[] {String.valueOf(this)}); + } XToolkit.awtLock(); try { @@ -887,7 +889,10 @@ public class XBaseWindow { XToolkit.awtLock(); try { XBaseWindow grabWindow = XAwtState.getGrabWindow(); - grabLog.log(Level.FINE, "UnGrab input on {0}", new Object[] {grabWindow}); + if (grabLog.isLoggable(Level.FINE)) { + grabLog.log(Level.FINE, "UnGrab input on {0}", + new Object[] {String.valueOf(grabWindow)}); + } if (grabWindow != null) { grabWindow.ungrabInputImpl(); if (!XToolkit.getSunAwtDisableGrab()) { @@ -940,7 +945,7 @@ public class XBaseWindow { XPropertyCache.clearCache(window, XAtom.get(msg.get_atom())); } if (eventLog.isLoggable(Level.FINER)) { - eventLog.log(Level.FINER, "{0}", new Object[] {msg}); + eventLog.log(Level.FINER, "{0}", new Object[] {String.valueOf(msg)}); } } @@ -1021,8 +1026,10 @@ public class XBaseWindow { } public void handleConfigureNotifyEvent(XEvent xev) { XConfigureEvent xe = xev.get_xconfigure(); - insLog.log(Level.FINER, "Configure, {0}", - new Object[] {xe}); + if (insLog.isLoggable(Level.FINER)) { + insLog.log(Level.FINER, "Configure, {0}", + new Object[] {String.valueOf(xe)}); + } x = xe.get_x(); y = xe.get_y(); width = xe.get_width(); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XCheckboxMenuItemPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XCheckboxMenuItemPeer.java index f2e1ef6f04b..b54dfbd9ec5 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XCheckboxMenuItemPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XCheckboxMenuItemPeer.java @@ -29,8 +29,6 @@ import java.awt.*; import java.awt.peer.*; import java.awt.event.*; -import java.util.logging.*; - import java.lang.reflect.Field; import sun.awt.SunToolkit; @@ -42,8 +40,6 @@ class XCheckboxMenuItemPeer extends XMenuItemPeer implements CheckboxMenuItemPee * ************************************************/ - private static Logger log = Logger.getLogger("sun.awt.X11.XCheckboxMenuItemPeer"); - /* * CheckboxMenuItem's fields */ diff --git a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java index cb842d4d64a..606f6dee138 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java @@ -253,7 +253,9 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget * Called when component receives focus */ public void focusGained(FocusEvent e) { - focusLog.log(Level.FINE, "{0}", new Object[] {e}); + if (focusLog.isLoggable(Level.FINE)) { + focusLog.log(Level.FINE, "{0}", new Object[] {String.valueOf(e)}); + } bHasFocus = true; } @@ -261,7 +263,9 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget * Called when component loses focus */ public void focusLost(FocusEvent e) { - focusLog.log(Level.FINE, "{0}", new Object[] {e}); + if (focusLog.isLoggable(Level.FINE)) { + focusLog.log(Level.FINE, "{0}", new Object[] {String.valueOf(e)}); + } bHasFocus = false; } @@ -414,7 +418,10 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget * @see java.awt.peer.ComponentPeer */ public void setEnabled(boolean value) { - enableLog.log(Level.FINE, "{0}ing {1}", new Object[] {(value?"Enabl":"Disabl"), this}); + if (enableLog.isLoggable(Level.FINE)) { + enableLog.log(Level.FINE, "{0}ing {1}", + new Object[] {(value?"Enabl":"Disabl"), String.valueOf(this)}); + } boolean repaintNeeded = (enabled != value); enabled = value; if (target instanceof Container) { @@ -1262,7 +1269,10 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget * ButtonPress, ButtonRelease, KeyPress, KeyRelease, EnterNotify, LeaveNotify, MotionNotify */ protected boolean isEventDisabled(XEvent e) { - enableLog.log(Level.FINEST, "Component is {1}, checking for disabled event {0}", new Object[] {e, (isEnabled()?"enabled":"disable")}); + if (enableLog.isLoggable(Level.FINEST)) { + enableLog.log(Level.FINEST, "Component is {1}, checking for disabled event {0}", + new Object[] {String.valueOf(e), (isEnabled()?"enabled":"disable")}); + } if (!isEnabled()) { switch (e.get_type()) { case XConstants.ButtonPress: @@ -1272,7 +1282,9 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget case XConstants.EnterNotify: case XConstants.LeaveNotify: case XConstants.MotionNotify: - enableLog.log(Level.FINER, "Event {0} is disable", new Object[] {e}); + if (enableLog.isLoggable(Level.FINER)) { + enableLog.log(Level.FINER, "Event {0} is disable", new Object[] {String.valueOf(e)}); + } return true; } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java index 6a32fe9bdc3..93ddcae2879 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java @@ -116,8 +116,10 @@ public final class XContentWindow extends XWindow { if (in != null) { newBounds.setLocation(-in.left, -in.top); } - if (insLog.isLoggable(Level.FINE)) insLog.log(Level.FINE, "Setting content bounds {0}, old bounds {1}", - new Object[] {newBounds, getBounds()}); + if (insLog.isLoggable(Level.FINE)) { + insLog.log(Level.FINE, "Setting content bounds {0}, old bounds {1}", + new Object[] {String.valueOf(newBounds), String.valueOf(getBounds())}); + } // Fix for 5023533: // Change in the size of the content window means, well, change of the size // Change in the location of the content window means change in insets diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java index 417cd3b0062..a067d7a71bd 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java @@ -79,7 +79,9 @@ abstract class XDecoratedPeer extends XWindowPeer { Rectangle bounds = (Rectangle)params.get(BOUNDS); dimensions = new WindowDimensions(bounds, getRealInsets(), false); params.put(BOUNDS, dimensions.getClientRect()); - insLog.log(Level.FINE, "Initial dimensions {0}", new Object[] { dimensions }); + if (insLog.isLoggable(Level.FINE)) { + insLog.log(Level.FINE, "Initial dimensions {0}",new Object[] { String.valueOf(dimensions) }); + } // Deny default processing of these events on the shell - proxy will take care of // them instead @@ -265,7 +267,10 @@ abstract class XDecoratedPeer extends XWindowPeer { wm_set_insets = XWM.getInsetsFromProp(getWindow(), changedAtom); } - insLog.log(Level.FINER, "FRAME_EXTENTS: {0}", new Object[]{wm_set_insets}); + if (insLog.isLoggable(Level.FINER)) { + insLog.log(Level.FINER, "FRAME_EXTENTS: {0}", + new Object[]{String.valueOf(wm_set_insets)}); + } if (wm_set_insets != null) { wm_set_insets = copy(wm_set_insets); @@ -331,7 +336,10 @@ abstract class XDecoratedPeer extends XWindowPeer { // Check if we have insets provided by the WM Insets correctWM = getWMSetInsets(null); if (correctWM != null) { - insLog.log(Level.FINER, "wm-provided insets {0}", new Object[]{correctWM}); + if (insLog.isLoggable(Level.FINER)) { + insLog.log(Level.FINER, "wm-provided insets {0}", + new Object[]{String.valueOf(correctWM)}); + } // If these insets are equal to our current insets - no actions are necessary Insets dimInsets = dimensions.getInsets(); if (correctWM.equals(dimInsets)) { @@ -345,7 +353,9 @@ abstract class XDecoratedPeer extends XWindowPeer { correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent()); if (correctWM != null) { - insLog.log(Level.FINER, "correctWM {0}", new Object[] {correctWM}); + if (insLog.isLoggable(Level.FINE)) { + insLog.log(Level.FINER, "correctWM {0}", new Object[] {String.valueOf(correctWM)}); + } } else { insLog.log(Level.FINER, "correctWM insets are not available, waiting for configureNotify"); } @@ -368,7 +378,10 @@ abstract class XDecoratedPeer extends XWindowPeer { * initial insets were wrong (most likely they were). */ Insets correction = difference(correctWM, currentInsets); - insLog.log(Level.FINEST, "Corrention {0}", new Object[] {correction}); + if (insLog.isLoggable(Level.FINEST)) { + insLog.log(Level.FINEST, "Corrention {0}", + new Object[] {String.valueOf(correction)}); + } if (!isNull(correction)) { currentInsets = copy(correctWM); applyGuessedInsets(); @@ -453,7 +466,7 @@ abstract class XDecoratedPeer extends XWindowPeer { Insets in = copy(getRealInsets()); in.top += getMenuBarHeight(); if (insLog.isLoggable(Level.FINEST)) { - insLog.log(Level.FINEST, "Get insets returns {0}", new Object[] {in}); + insLog.log(Level.FINEST, "Get insets returns {0}", new Object[] {String.valueOf(in)}); } return in; } @@ -610,7 +623,7 @@ abstract class XDecoratedPeer extends XWindowPeer { break; } if (insLog.isLoggable(Level.FINE)) insLog.log(Level.FINE, "For the operation {0} new dimensions are {1}", - new Object[] {operationToString(operation), dims}); + new Object[] {operationToString(operation), String.valueOf(dims)}); reshape(dims, operation, userReshape); } @@ -640,7 +653,9 @@ abstract class XDecoratedPeer extends XWindowPeer { public void handleConfigureNotifyEvent(XEvent xev) { assert (SunToolkit.isAWTLockHeldByCurrentThread()); XConfigureEvent xe = xev.get_xconfigure(); - insLog.log(Level.FINE, "Configure notify {0}", new Object[] {xe}); + if (insLog.isLoggable(Level.FINE)) { + insLog.log(Level.FINE, "Configure notify {0}", new Object[] {String.valueOf(xe)}); + } // XXX: should really only consider synthetic events, but if (isReparented()) { @@ -732,7 +747,10 @@ abstract class XDecoratedPeer extends XWindowPeer { case XWM.SAWFISH_WM: { Point xlocation = queryXLocation(); - if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "New X location: {0}", new Object[]{xlocation}); + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINE, "New X location: {0}", + new Object[]{String.valueOf(xlocation)}); + } if (xlocation != null) { newLocation = xlocation; } @@ -749,8 +767,10 @@ abstract class XDecoratedPeer extends XWindowPeer { copy(currentInsets), true); - insLog.log(Level.FINER, "Insets are {0}, new dimensions {1}", - new Object[] {currentInsets, newDimensions}); + if (insLog.isLoggable(Level.FINER)) { + insLog.log(Level.FINER, "Insets are {0}, new dimensions {1}", + new Object[] {String.valueOf(currentInsets), String.valueOf(newDimensions)}); + } checkIfOnNewScreen(newDimensions.getBounds()); @@ -917,7 +937,7 @@ abstract class XDecoratedPeer extends XWindowPeer { Point location = target.getLocation(); if (insLog.isLoggable(Level.FINE)) insLog.log(Level.FINE, "getLocationOnScreen {0} not reparented: {1} ", - new Object[] {this, location}); + new Object[] {String.valueOf(this), String.valueOf(location)}); return location; } } finally { @@ -954,7 +974,10 @@ abstract class XDecoratedPeer extends XWindowPeer { } public void setVisible(boolean vis) { - log.log(Level.FINER, "Setting {0} to visible {1}", new Object[] {this, Boolean.valueOf(vis)}); + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINER, "Setting {0} to visible {1}", + new Object[] {String.valueOf(this), Boolean.valueOf(vis)}); + } if (vis && !isVisible()) { XWM.setShellDecor(this); super.setVisible(vis); @@ -1005,7 +1028,9 @@ abstract class XDecoratedPeer extends XWindowPeer { } private void handleWmTakeFocus(XClientMessageEvent cl) { - focusLog.log(Level.FINE, "WM_TAKE_FOCUS on {0}", new Object[]{this}); + if (focusLog.isLoggable(Level.FINE)) { + focusLog.log(Level.FINE, "WM_TAKE_FOCUS on {0}", new Object[]{String.valueOf(this)}); + } requestWindowFocus(cl.get_data(1), true); } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetProtocol.java b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetProtocol.java index 7a7c7c10ee2..13ff5bf4af9 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetProtocol.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetProtocol.java @@ -117,7 +117,7 @@ abstract class XDropTargetProtocol { EmbedderRegistryEntry entry = getEmbedderRegistryEntry(toplevel); if (logger.isLoggable(Level.FINEST)) { - logger.log(Level.FINEST, " entry={0}", new Object[] {entry}); + logger.log(Level.FINEST, " entry={0}", new Object[] {String.valueOf(entry)}); } // Window not registered as an embedder for this protocol. if (entry == null) { @@ -138,7 +138,8 @@ abstract class XDropTargetProtocol { long proxy = entry.getProxy(); if (logger.isLoggable(Level.FINEST)) { - logger.log(Level.FINEST, " proxy={0} toplevel={1}", new Object[] {proxy, toplevel}); + logger.log(Level.FINEST, " proxy={0} toplevel={1}", + new Object[] {String.valueOf(proxy), String.valueOf(toplevel)}); } if (proxy == 0) { proxy = toplevel; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XFocusProxyWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XFocusProxyWindow.java index 361ef87eeb6..bd30f6922a5 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XFocusProxyWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XFocusProxyWindow.java @@ -34,7 +34,6 @@ import java.util.logging.*; * and therefore X doesn't control focus after we have set it to proxy. */ public class XFocusProxyWindow extends XBaseWindow { - private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XFocusProxyWindow"); XWindowPeer owner; public XFocusProxyWindow(XWindowPeer owner) { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java b/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java index 22cb163ebbb..b1e422326af 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java @@ -283,7 +283,9 @@ class XFramePeer extends XDecoratedPeer implements FramePeer { super.handlePropertyNotify(xev); XPropertyEvent ev = xev.get_xproperty(); - log.log(Level.FINER, "Property change {0}", new Object[] {ev}); + if (log.isLoggable(Level.FINER)) { + log.log(Level.FINER, "Property change {0}", new Object[] {String.valueOf(ev)}); + } /* * Let's see if this is a window state protocol message, and * if it is - decode a new state in terms of java constants. diff --git a/jdk/src/solaris/classes/sun/awt/X11/XIconWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XIconWindow.java index a6211a0e0b6..e9643c9153c 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XIconWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XIconWindow.java @@ -75,7 +75,7 @@ public class XIconWindow extends XBaseWindow { XIconSize[] res = new XIconSize[count]; for (int i = 0; i < count; i++, sizes_ptr += XIconSize.getSize()) { res[i] = new XIconSize(sizes_ptr); - log.log(Level.FINEST, "sizes_ptr[{1}] = {0}", new Object[] {res[i], Integer.valueOf(i)}); + log.log(Level.FINEST, "sizes_ptr[{1}] = {0}", new Object[] {String.valueOf(res[i]), Integer.valueOf(i)}); } return res; } finally { @@ -92,7 +92,10 @@ public class XIconWindow extends XBaseWindow { } XIconSize[] sizeList = getIconSizes(); - log.log(Level.FINEST, "Icon sizes: {0}", new Object[] {sizeList}); + + if (log.isLoggable(Level.FINEST)) { + log.log(Level.FINEST, "Icon sizes: {0}", new Object[] {String.valueOf(sizeList)}); + } if (sizeList == null) { // No icon sizes so we simply fall back to 16x16 return new Dimension(16, 16); @@ -444,7 +447,9 @@ public class XIconWindow extends XBaseWindow { } Dimension iconSize = getIconSize(width, height); if (iconSize != null) { - log.log(Level.FINEST, "Icon size: {0}", iconSize); + if (log.isLoggable(Level.FINEST)) { + log.log(Level.FINEST, "Icon size: {0}", String.valueOf(iconSize)); + } iconWidth = iconSize.width; iconHeight = iconSize.height; } else { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XInputMethod.java b/jdk/src/solaris/classes/sun/awt/X11/XInputMethod.java index 86df2073d6d..756c0ae1262 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XInputMethod.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XInputMethod.java @@ -108,7 +108,10 @@ public class XInputMethod extends X11InputMethod { client = getParent(client); peer = (XComponentPeer)XToolkit.targetToPeer(client); } - log.log(Level.FINE, "Peer is {0}, client is {1}", new Object[] {peer, client}); + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINE, "Peer is {0}, client is {1}", + new Object[] {String.valueOf(peer), String.valueOf(client)}); + } if (peer != null) return peer; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java index ec80cebcec1..99e8d3fcac1 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java @@ -43,8 +43,6 @@ public class XMenuItemPeer implements MenuItemPeer { * ************************************************/ - private static Logger log = Logger.getLogger("sun.awt.X11.XMenuItemPeer"); - /* * Primary members */ diff --git a/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java b/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java index 1bc8829d9bc..02a570837b0 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java @@ -54,7 +54,11 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt private void setInitialState(XWindowPeer window, int state) { XAtomList old_state = window.getNETWMState(); - log.log(Level.FINE, "Current state of the window {0} is {1}", new Object[] {window, old_state}); + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINE, "Current state of the window {0} is {1}", + new Object[] {String.valueOf(window), + String.valueOf(old_state)}); + } if ((state & Frame.MAXIMIZED_VERT) != 0) { old_state.add(XA_NET_WM_STATE_MAXIMIZED_VERT); } else { @@ -65,7 +69,10 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt } else { old_state.remove(XA_NET_WM_STATE_MAXIMIZED_HORZ); } - log.log(Level.FINE, "Setting initial state of the window {0} to {1}", new Object[] {window, old_state}); + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINE, "Setting initial state of the window {0} to {1}", + new Object[] {String.valueOf(window), String.valueOf(old_state)}); + } window.setNETWMState(old_state); } @@ -180,7 +187,11 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt req.set_data(1, state.getAtom()); // Fix for 6735584: req.data[2] must be set to 0 when only one property is changed req.set_data(2, 0); - log.log(Level.FINE, "Setting _NET_STATE atom {0} on {1} for {2}", new Object[] {state, window, Boolean.valueOf(isAdd)}); + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINE, "Setting _NET_STATE atom {0} on {1} for {2}", + new Object[] {String.valueOf(state), String.valueOf(window), + Boolean.valueOf(isAdd)}); + } XToolkit.awtLock(); try { XlibWrapper.XSendEvent(XToolkit.getDisplay(), @@ -212,13 +223,19 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt requestState(window, state, set); } else { XAtomList net_wm_state = window.getNETWMState(); - log.log(Level.FINE, "Current state on {0} is {1}", new Object[] {window, net_wm_state}); + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINE, "Current state on {0} is {1}", + new Object[] {String.valueOf(window), net_wm_state}); + } if (!set) { net_wm_state.remove(state); } else { net_wm_state.add(state); } - log.log(Level.FINE, "Setting states on {0} to {1}", new Object[] {window, net_wm_state}); + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINE, "Setting states on {0} to {1}", + new Object[] {String.valueOf(window), net_wm_state}); + } window.setNETWMState(net_wm_state); } XToolkit.XSync(); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XProtocol.java b/jdk/src/solaris/classes/sun/awt/X11/XProtocol.java index 328f1a88775..9fe1d02956b 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XProtocol.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XProtocol.java @@ -54,7 +54,11 @@ class XProtocol { } finally { if (firstCheck) { firstCheck = false; - log.log(Level.FINE, "{0}:{1} supports {2}", new Object[] {this, listName, protocols}); + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINE, "{0}:{1} supports {2}", + new Object[] {String.valueOf(this), String.valueOf(listName), + String.valueOf(protocols)}); + } } } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XQueryTree.java b/jdk/src/solaris/classes/sun/awt/X11/XQueryTree.java index eaace18e9ff..e3e4901a4d9 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XQueryTree.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XQueryTree.java @@ -32,7 +32,6 @@ import java.util.logging.*; public class XQueryTree { private static Unsafe unsafe = XlibWrapper.unsafe; - private static final Logger log = Logger.getLogger("sun.awt.X11.XQueryTree"); private boolean __executed = false; long _w; long root_ptr = unsafe.allocateMemory(Native.getLongSize()); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java index 14839c7b671..cba955ad116 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -624,7 +624,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable { } if (eventLog.isLoggable(Level.FINER)) { - eventLog.log(Level.FINER, "{0}", ev); + eventLog.log(Level.FINER, "{0}", String.valueOf(ev)); } // Check if input method consumes the event @@ -1837,8 +1837,10 @@ public final class XToolkit extends UNIXToolkit implements Runnable { if (timeoutTaskLog.isLoggable(Level.FINER)) { timeoutTaskLog.log(Level.FINER, "XToolkit.schedule(): current time={0}" + "; interval={1}" + - "; task being added={2}" + "; tasks before addition={3}", new Object[] { - Long.valueOf(System.currentTimeMillis()), Long.valueOf(interval), task, timeoutTasks}); + "; task being added={2}" + "; tasks before addition={3}", + new Object[] {Long.valueOf(System.currentTimeMillis()), + Long.valueOf(interval), String.valueOf(task), + String.valueOf(timeoutTasks)}); } if (timeoutTasks == null) { @@ -1883,7 +1885,8 @@ public final class XToolkit extends UNIXToolkit implements Runnable { private static void callTimeoutTasks() { if (timeoutTaskLog.isLoggable(Level.FINER)) { timeoutTaskLog.log(Level.FINER, "XToolkit.callTimeoutTasks(): current time={0}" + - "; tasks={1}", new Object[] {Long.valueOf(System.currentTimeMillis()), timeoutTasks}); + "; tasks={1}", + new Object[] {Long.valueOf(System.currentTimeMillis()), String.valueOf(timeoutTasks)}); } if (timeoutTasks == null || timeoutTasks.isEmpty()) { @@ -1901,7 +1904,8 @@ public final class XToolkit extends UNIXToolkit implements Runnable { if (timeoutTaskLog.isLoggable(Level.FINER)) { timeoutTaskLog.log(Level.FINER, "XToolkit.callTimeoutTasks(): current time={0}" + - "; about to run task={1}", new Object[] {Long.valueOf(currentTime), task}); + "; about to run task={1}", + new Object[] {Long.valueOf(currentTime), String.valueOf(task)}); } try { @@ -2358,7 +2362,10 @@ public final class XToolkit extends UNIXToolkit implements Runnable { // Wait for selection notify for oops on win long event_number = getEventNumber(); XAtom atom = XAtom.get("WM_S0"); - eventLog.log(Level.FINER, "WM_S0 selection owner {0}", new Object[] {XlibWrapper.XGetSelectionOwner(getDisplay(), atom.getAtom())}); + if (eventLog.isLoggable(Level.FINER)) { + eventLog.log(Level.FINER, "WM_S0 selection owner {0}", + new Object[] {String.valueOf(XlibWrapper.XGetSelectionOwner(getDisplay(), atom.getAtom()))}); + } XlibWrapper.XConvertSelection(getDisplay(), atom.getAtom(), XAtom.get("VERSION").getAtom(), oops.getAtom(), win.getWindow(), XConstants.CurrentTime); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java index b1243abacf7..f3b6310c003 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java @@ -129,14 +129,17 @@ public class XTrayIconPeer implements TrayIconPeer, // If both the height and the width differ from the fixed size then WM // must level at least one side to the fixed size. For some reason it may take // a few hops (even after reparenting) and we have to skip the intermediate ones. - ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Skipping as intermediate resizing.", - XTrayIconPeer.this); + if (ctrLog.isLoggable(Level.FINE)) { + ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Skipping as intermediate resizing.", + String.valueOf(XTrayIconPeer.this)); + } return; } else if (ce.get_height() > TRAY_ICON_HEIGHT) { - - ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Centering by \"Y\".", - XTrayIconPeer.this); + if (ctrLog.isLoggable(Level.FINE)) { + ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Centering by \"Y\".", + String.valueOf(XTrayIconPeer.this)); + } XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), eframeParentID, ce.get_x(), @@ -147,9 +150,10 @@ public class XTrayIconPeer implements TrayIconPeer, ex_width = 0; } else if (ce.get_width() > TRAY_ICON_WIDTH) { - - ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Centering by \"X\".", - XTrayIconPeer.this); + if (ctrLog.isLoggable(Level.FINE)) { + ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Centering by \"X\".", + String.valueOf(XTrayIconPeer.this)); + } XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), eframeParentID, ce.get_x()+ce.get_width()/2 - TRAY_ICON_WIDTH/2, @@ -165,25 +169,32 @@ public class XTrayIconPeer implements TrayIconPeer, // In this case the parent window also lose centering. We have to restore it. if (ex_height != 0) { - - ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Move detected. Centering by \"Y\".", - XTrayIconPeer.this); + if (ctrLog.isLoggable(Level.FINE)) { + ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}." + + " Move detected. Centering by \"Y\".", + String.valueOf(XTrayIconPeer.this)); + } XlibWrapper.XMoveWindow(XToolkit.getDisplay(), eframeParentID, ce.get_x(), ce.get_y() + ex_height/2 - TRAY_ICON_HEIGHT/2); } else if (ex_width != 0) { - - ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Move detected. Centering by \"X\".", - XTrayIconPeer.this); + if (ctrLog.isLoggable(Level.FINE)) { + ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}." + + "Move detected. Centering by \"X\".", + String.valueOf(XTrayIconPeer.this)); + } XlibWrapper.XMoveWindow(XToolkit.getDisplay(), eframeParentID, ce.get_x() + ex_width/2 - TRAY_ICON_WIDTH/2, ce.get_y()); } else { - ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Move detected. Skipping.", - XTrayIconPeer.this); + if (ctrLog.isLoggable(Level.FINE)) { + ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}." + + "Move detected. Skipping.", + String.valueOf(XTrayIconPeer.this)); + } } } old_x = ce.get_x(); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWM.java b/jdk/src/solaris/classes/sun/awt/X11/XWM.java index 4d49dee60e0..74aa3119b62 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWM.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWM.java @@ -401,7 +401,10 @@ final class XWM static boolean isCDE() { if (!XA_DT_SM_WINDOW_INFO.isInterned()) { - log.log(Level.FINER, "{0} is not interned", new Object[] {XA_DT_SM_WINDOW_INFO}); + if (log.isLoggable(Level.FINER)) { + log.log(Level.FINER, "{0} is not interned", + new Object[] {String.valueOf(XA_DT_SM_WINDOW_INFO)}); + } return false; } @@ -432,7 +435,10 @@ final class XWM /* Now check that this window has _DT_SM_STATE_INFO (ignore contents) */ if (!XA_DT_SM_STATE_INFO.isInterned()) { - log.log(Level.FINER, "{0} is not interned", new Object[] {XA_DT_SM_STATE_INFO}); + if (log.isLoggable(Level.FINER)) { + log.log(Level.FINER, "{0} is not interned", + new Object[] {String.valueOf(XA_DT_SM_STATE_INFO)}); + } return false; } WindowPropertyGetter getter2 = @@ -596,7 +602,10 @@ final class XWM */ if (!XA_ICEWM_WINOPTHINT.isInterned()) { - log.log(Level.FINER, "{0} is not interned", new Object[] {XA_ICEWM_WINOPTHINT}); + if (log.isLoggable(Level.FINER)) { + log.log(Level.FINER, "{0} is not interned", + String.valueOf(XA_ICEWM_WINOPTHINT)); + } return false; } @@ -629,7 +638,10 @@ final class XWM */ static boolean isIceWM() { if (!XA_ICEWM_WINOPTHINT.isInterned()) { - log.log(Level.FINER, "{0} is not interned", new Object[] {XA_ICEWM_WINOPTHINT}); + if (log.isLoggable(Level.FINER)) { + log.log(Level.FINER, "{0} is not interned", + new Object[] {String.valueOf(XA_ICEWM_WINOPTHINT)}); + } return false; } @@ -1354,7 +1366,9 @@ final class XWM XNETProtocol net_protocol = getWM().getNETProtocol(); if (net_protocol != null && net_protocol.active()) { Insets insets = getInsetsFromProp(window, XA_NET_FRAME_EXTENTS); - insLog.log(Level.FINE, "_NET_FRAME_EXTENTS: {0}", insets); + if (insLog.isLoggable(Level.FINE)) { + insLog.log(Level.FINE, "_NET_FRAME_EXTENTS: {0}", String.valueOf(insets)); + } if (insets != null) { return insets; @@ -1495,7 +1509,10 @@ final class XWM * [mwm, e!, kwin, fvwm2 ... ] */ Insets correctWM = XWM.getInsetsFromExtents(window); - insLog.log(Level.FINER, "Got insets from property: {0}", correctWM); + if (insLog.isLoggable(Level.FINER)) { + insLog.log(Level.FINER, "Got insets from property: {0}", + String.valueOf(correctWM)); + } if (correctWM == null) { correctWM = new Insets(0,0,0,0); @@ -1556,7 +1573,10 @@ final class XWM } case XWM.OTHER_WM: default: { /* this is very similar to the E! case above */ - insLog.log(Level.FINEST, "Getting correct insets for OTHER_WM/default, parent: {0}", parent); + if (insLog.isLoggable(Level.FINEST)) { + insLog.log(Level.FINEST, "Getting correct insets for OTHER_WM/default, parent: {0}", + String.valueOf(parent)); + } syncTopLevelPos(parent, lwinAttr); int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(), window, lwinAttr.pData); @@ -1583,8 +1603,11 @@ final class XWM && lwinAttr.get_width()+2*lwinAttr.get_border_width() == pattr.get_width() && lwinAttr.get_height()+2*lwinAttr.get_border_width() == pattr.get_height()) { - insLog.log(Level.FINEST, "Double reparenting detected, pattr({2})={0}, lwinAttr({3})={1}", - new Object[] {lwinAttr, pattr, parent, window}); + if (insLog.isLoggable(Level.FINEST)) { + insLog.log(Level.FINEST, "Double reparenting detected, pattr({2})={0}, lwinAttr({3})={1}", + new Object[] {String.valueOf(lwinAttr), String.valueOf(pattr), + String.valueOf(parent), String.valueOf(window)}); + } lwinAttr.set_x(pattr.get_x()); lwinAttr.set_y(pattr.get_y()); lwinAttr.set_border_width(lwinAttr.get_border_width()+pattr.get_border_width()); @@ -1611,8 +1634,11 @@ final class XWM * widths and inner/outer distinction, so for the time * being, just ignore it. */ - insLog.log(Level.FINEST, "Attrs before calculation: pattr({2})={0}, lwinAttr({3})={1}", - new Object[] {lwinAttr, pattr, parent, window}); + if (insLog.isLoggable(Level.FINEST)) { + insLog.log(Level.FINEST, "Attrs before calculation: pattr({2})={0}, lwinAttr({3})={1}", + new Object[] {String.valueOf(lwinAttr), String.valueOf(pattr), + String.valueOf(parent), String.valueOf(window)}); + } correctWM = new Insets(lwinAttr.get_y() + lwinAttr.get_border_width(), lwinAttr.get_x() + lwinAttr.get_border_width(), pattr.get_height() - (lwinAttr.get_y() + lwinAttr.get_height() + 2*lwinAttr.get_border_width()), diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java index f1c3c675b6c..4f7d5689604 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java @@ -997,8 +997,10 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { Rectangle oldBounds = getBounds(); super.handleConfigureNotifyEvent(xev); - insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}", - new Object[] {xev.get_xconfigure(), isEventDisabled(xev)}); + if (insLog.isLoggable(Level.FINER)) { + insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}", + new Object[] {String.valueOf(xev.get_xconfigure()), isEventDisabled(xev)}); + } if (isEventDisabled(xev)) { return; } @@ -1017,7 +1019,9 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { public void handleMapNotifyEvent(XEvent xev) { super.handleMapNotifyEvent(xev); - log.log(Level.FINE, "Mapped {0}", new Object[] {this}); + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINE, "Mapped {0}", new Object[] {String.valueOf(this)}); + } if (isEventDisabled(xev)) { return; } @@ -1333,10 +1337,16 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { void updateSizeHints(int x, int y, int width, int height) { long flags = XUtilConstants.PSize | (isLocationByPlatform() ? 0 : (XUtilConstants.PPosition | XUtilConstants.USPosition)); if (!isResizable()) { - log.log(Level.FINER, "Window {0} is not resizable", new Object[] {this}); + if (log.isLoggable(Level.FINER)) { + log.log(Level.FINER, "Window {0} is not resizable", + new Object[] {String.valueOf(this)}); + } flags |= XUtilConstants.PMinSize | XUtilConstants.PMaxSize; } else { - log.log(Level.FINER, "Window {0} is resizable", new Object[] {this}); + if (keyEventLog.isLoggable(Level.FINER)) { + log.log(Level.FINER, "Window {0} is resizable", + new Object[] {String.valueOf(this)}); + } } setSizeHints(flags, x, y, width, height); } @@ -1344,10 +1354,16 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { void updateSizeHints(int x, int y) { long flags = isLocationByPlatform() ? 0 : (XUtilConstants.PPosition | XUtilConstants.USPosition); if (!isResizable()) { - log.log(Level.FINER, "Window {0} is not resizable", new Object[] {this}); + if (log.isLoggable(Level.FINER)) { + log.log(Level.FINER, "Window {0} is not resizable", + new Object[] {String.valueOf(this)}); + } flags |= XUtilConstants.PMinSize | XUtilConstants.PMaxSize | XUtilConstants.PSize; } else { - log.log(Level.FINER, "Window {0} is resizable", new Object[] {this}); + if (log.isLoggable(Level.FINER)) { + log.log(Level.FINER, "Window {0} is resizable", + new Object[] {String.valueOf(this)}); + } } setSizeHints(flags, x, y, width, height); } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java index b1646413b79..0c3a12a8fed 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java @@ -354,7 +354,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, if (iconLog.isLoggable(Level.FINEST)) { iconLog.log(Level.FINEST, ">>> Sizes of icon images:"); for (Iterator i = icons.iterator(); i.hasNext(); ) { - iconLog.log(Level.FINEST, " {0}", i.next()); + iconLog.log(Level.FINEST, " {0}", String.valueOf(i.next())); } } } @@ -769,7 +769,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, public void handleFocusEvent(XEvent xev) { XFocusChangeEvent xfe = xev.get_xfocus(); FocusEvent fe; - focusLog.log(Level.FINE, "{0}", new Object[] {xfe}); + if (focusLog.isLoggable(Level.FINE)) { + focusLog.log(Level.FINE, "{0}", new Object[] {String.valueOf(xfe)}); + } if (isEventDisabled(xev)) { return; } @@ -1388,7 +1390,10 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, synchronized(getStateLock()) { XDialogPeer blockerPeer = (XDialogPeer) ComponentAccessor.getPeer(d); if (blocked) { - log.log(Level.FINE, "{0} is blocked by {1}", new Object[] { this, blockerPeer}); + if (log.isLoggable(Level.FINE)) { + log.log(Level.FINE, "{0} is blocked by {1}", + new Object[] { String.valueOf(this), String.valueOf(blockerPeer)}); + } modalBlocker = d; if (isReparented() || XWM.isNonReparentingWM()) { @@ -1866,7 +1871,8 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, XCrossingEvent xce = xev.get_xcrossing(); if (grabLog.isLoggable(Level.FINE)) { grabLog.log(Level.FINE, "{0}, when grabbed {1}, contains {2}", - new Object[] {xce, isGrabbed(), containsGlobal(xce.get_x_root(), xce.get_y_root())}); + new Object[] {String.valueOf(xce), isGrabbed(), + containsGlobal(xce.get_x_root(), xce.get_y_root())}); } if (isGrabbed()) { // When window is grabbed, all events are dispatched to @@ -1877,7 +1883,10 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, // since it generates MOUSE_ENTERED/MOUSE_EXITED for frame and dialog. // (fix for 6390326) XBaseWindow target = XToolkit.windowToXWindow(xce.get_window()); - grabLog.log(Level.FINER, " - Grab event target {0}", new Object[] {target}); + if (grabLog.isLoggable(Level.FINER)) { + grabLog.log(Level.FINER, " - Grab event target {0}", + new Object[] {String.valueOf(target)}); + } if (target != null && target != this) { target.dispatchEvent(xev); return; @@ -1890,7 +1899,8 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, XMotionEvent xme = xev.get_xmotion(); if (grabLog.isLoggable(Level.FINE)) { grabLog.log(Level.FINER, "{0}, when grabbed {1}, contains {2}", - new Object[] {xme, isGrabbed(), containsGlobal(xme.get_x_root(), xme.get_y_root())}); + new Object[] {String.valueOf(xme), isGrabbed(), + containsGlobal(xme.get_x_root(), xme.get_y_root())}); } if (isGrabbed()) { boolean dragging = false; @@ -1919,7 +1929,10 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, xme.set_x(localCoord.x); xme.set_y(localCoord.y); } - grabLog.log(Level.FINER, " - Grab event target {0}", new Object[] {target}); + if (grabLog.isLoggable(Level.FINER)) { + grabLog.log(Level.FINER, " - Grab event target {0}", + new Object[] {String.valueOf(target)}); + } if (target != null) { if (target != getContentXWindow() && target != this) { target.dispatchEvent(xev); @@ -1953,7 +1966,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, } if (grabLog.isLoggable(Level.FINE)) { grabLog.log(Level.FINE, "{0}, when grabbed {1}, contains {2} ({3}, {4}, {5}x{6})", - new Object[] {xbe, isGrabbed(), containsGlobal(xbe.get_x_root(), xbe.get_y_root()), getAbsoluteX(), getAbsoluteY(), getWidth(), getHeight()}); + new Object[] {String.valueOf(xbe), isGrabbed(), + containsGlobal(xbe.get_x_root(), xbe.get_y_root()), + getAbsoluteX(), getAbsoluteY(), getWidth(), getHeight()}); } if (isGrabbed()) { // When window is grabbed, all events are dispatched to @@ -1962,7 +1977,10 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, // translation) XBaseWindow target = XToolkit.windowToXWindow(xbe.get_window()); try { - grabLog.log(Level.FINER, " - Grab event target {0} (press target {1})", new Object[] {target, pressTarget}); + if (grabLog.isLoggable(Level.FINER)) { + grabLog.log(Level.FINER, " - Grab event target {0} (press target {1})", + new Object[] {String.valueOf(target), String.valueOf(pressTarget)}); + } if (xbe.get_type() == XConstants.ButtonPress && xbe.get_button() == XConstants.buttons[0]) { @@ -1995,7 +2013,10 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, // Outside this toplevel hierarchy // According to the specification of UngrabEvent, post it // when press occurs outside of the window and not on its owned windows - grabLog.log(Level.FINE, "Generating UngrabEvent on {0} because not inside of shell", this); + if (grabLog.isLoggable(Level.FINE)) { + grabLog.log(Level.FINE, "Generating UngrabEvent on {0} because not inside of shell", + String.valueOf(this)); + } postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource())); return; } @@ -2013,18 +2034,27 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, // toplevel == null - outside of // hierarchy, toplevel is Dialog - should // send ungrab (but shouldn't for Window) - grabLog.log(Level.FINE, "Generating UngrabEvent on {0} because hierarchy ended", this); + if (grabLog.isLoggable(Level.FINE)) { + grabLog.log(Level.FINE, "Generating UngrabEvent on {0} because hierarchy ended", + String.valueOf(this)); + } postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource())); } } else { // toplevel is null - outside of hierarchy - grabLog.log(Level.FINE, "Generating UngrabEvent on {0} because toplevel is null", this); + if (grabLog.isLoggable(Level.FINE)) { + grabLog.log(Level.FINE, "Generating UngrabEvent on {0} because toplevel is null", + String.valueOf(this)); + } postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource())); return; } } else { // target doesn't map to XAWT window - outside of hierarchy - grabLog.log(Level.FINE, "Generating UngrabEvent on because target is null {0}", this); + if (grabLog.isLoggable(Level.FINE)) { + grabLog.log(Level.FINE, "Generating UngrabEvent on because target is null {0}", + String.valueOf(this)); + } postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource())); return; } diff --git a/jdk/src/windows/classes/sun/awt/windows/WMenuItemPeer.java b/jdk/src/windows/classes/sun/awt/windows/WMenuItemPeer.java index e1523268861..7080de47ad6 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WMenuItemPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WMenuItemPeer.java @@ -35,7 +35,7 @@ import java.util.logging.Logger; import java.util.logging.Level; class WMenuItemPeer extends WObjectPeer implements MenuItemPeer { - private static final Logger log = Logger.getLogger("sun.awt.WMenuItemPeer"); + private static final Logger log = Logger.getLogger("sun.awt.windows.WMenuItemPeer"); static { initIDs(); diff --git a/jdk/src/windows/classes/sun/awt/windows/WPanelPeer.java b/jdk/src/windows/classes/sun/awt/windows/WPanelPeer.java index 3b4af6dd1f6..4f38013f328 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WPanelPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WPanelPeer.java @@ -34,7 +34,6 @@ import java.util.logging.*; class WPanelPeer extends WCanvasPeer implements PanelPeer { - private static final Logger log = Logger.getLogger("sun.awt.windows.WPanelPeer"); // ComponentPeer overrides public void paint(Graphics g) { From 3b237a13dfc04adc3cf336daa3eaea4703e371c6 Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Thu, 20 Aug 2009 14:49:31 -0700 Subject: [PATCH 004/172] 6636650: (cl) Resurrected ClassLoaders can still have children Prevent classloader from resurrection Reviewed-by: hawtin --- .../share/classes/java/lang/ClassLoader.java | 85 ++++++------------- 1 file changed, 27 insertions(+), 58 deletions(-) diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java index d25100958a0..33236c00ff6 100644 --- a/jdk/src/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/share/classes/java/lang/ClassLoader.java @@ -186,11 +186,6 @@ public abstract class ClassLoader { parallelLoaders.add(ClassLoader.class); } - // If initialization succeed this is set to true and security checks will - // succeed. Otherwise the object is not initialized and the object is - // useless. - private final boolean initialized; - // The parent class loader for delegation // Note: VM hardcoded the offset of this field, thus all new fields // must be added *after* it. @@ -232,6 +227,31 @@ public abstract class ClassLoader { private final HashMap packages = new HashMap(); + private static Void checkCreateClassLoader() { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkCreateClassLoader(); + } + return null; + } + + private ClassLoader(Void unused, ClassLoader parent) { + this.parent = parent; + if (parallelLoaders.contains(this.getClass())) { + parallelLockMap = new ConcurrentHashMap(); + package2certs = new ConcurrentHashMap(); + domains = + Collections.synchronizedSet(new HashSet()); + assertionLock = new Object(); + } else { + // no finer-grained lock; lock on the classloader instance + parallelLockMap = null; + package2certs = new Hashtable(); + domains = new HashSet(); + assertionLock = this; + } + } + /** * Creates a new class loader using the specified parent class loader for * delegation. @@ -252,25 +272,7 @@ public abstract class ClassLoader { * @since 1.2 */ protected ClassLoader(ClassLoader parent) { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkCreateClassLoader(); - } - this.parent = parent; - if (parallelLoaders.contains(this.getClass())) { - parallelLockMap = new ConcurrentHashMap(); - package2certs = new ConcurrentHashMap(); - domains = - Collections.synchronizedSet(new HashSet()); - assertionLock = new Object(); - } else { - // no finer-grained lock; lock on the classloader instance - parallelLockMap = null; - package2certs = new Hashtable(); - domains = new HashSet(); - assertionLock = this; - } - initialized = true; + this(checkCreateClassLoader(), parent); } /** @@ -289,25 +291,7 @@ public abstract class ClassLoader { * of a new class loader. */ protected ClassLoader() { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkCreateClassLoader(); - } - this.parent = getSystemClassLoader(); - if (parallelLoaders.contains(this.getClass())) { - parallelLockMap = new ConcurrentHashMap(); - package2certs = new ConcurrentHashMap(); - domains = - Collections.synchronizedSet(new HashSet()); - assertionLock = new Object(); - } else { - // no finer-grained lock; lock on the classloader instance - parallelLockMap = null; - package2certs = new Hashtable(); - domains = new HashSet(); - assertionLock = this; - } - initialized = true; + this(checkCreateClassLoader(), getSystemClassLoader()); } // -- Class -- @@ -742,7 +726,6 @@ public abstract class ClassLoader { ProtectionDomain protectionDomain) throws ClassFormatError { - check(); protectionDomain = preDefineClass(name, protectionDomain); Class c = null; @@ -826,8 +809,6 @@ public abstract class ClassLoader { ProtectionDomain protectionDomain) throws ClassFormatError { - check(); - int len = b.remaining(); // Use byte[] if not a direct ByteBufer: @@ -972,7 +953,6 @@ public abstract class ClassLoader { * @see #defineClass(String, byte[], int, int) */ protected final void resolveClass(Class c) { - check(); resolveClass0(c); } @@ -1003,7 +983,6 @@ public abstract class ClassLoader { protected final Class findSystemClass(String name) throws ClassNotFoundException { - check(); ClassLoader system = getSystemClassLoader(); if (system == null) { if (!checkName(name)) @@ -1016,7 +995,6 @@ public abstract class ClassLoader { private Class findBootstrapClass0(String name) throws ClassNotFoundException { - check(); if (!checkName(name)) throw new ClassNotFoundException(name); return findBootstrapClass(name); @@ -1025,13 +1003,6 @@ public abstract class ClassLoader { private native Class findBootstrapClass(String name) throws ClassNotFoundException; - // Check to make sure the class loader has been initialized. - private void check() { - if (!initialized) { - throw new SecurityException("ClassLoader object not initialized"); - } - } - /** * Returns the class with the given binary name if this * loader has been recorded by the Java virtual machine as an initiating @@ -1047,7 +1018,6 @@ public abstract class ClassLoader { * @since 1.1 */ protected final Class findLoadedClass(String name) { - check(); if (!checkName(name)) return null; return findLoadedClass0(name); @@ -1068,7 +1038,6 @@ public abstract class ClassLoader { * @since 1.1 */ protected final void setSigners(Class c, Object[] signers) { - check(); c.setSigners(signers); } From fb19c4e1f91a437f84ec4f65e888651abcbf70a7 Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Thu, 20 Aug 2009 17:16:13 -0700 Subject: [PATCH 005/172] 6874407: Missing regression test for 6636650 Prevent classloader from resurrection Reviewed-by: hawtin --- .../lang/ClassLoader/UninitializedParent.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 jdk/test/java/lang/ClassLoader/UninitializedParent.java diff --git a/jdk/test/java/lang/ClassLoader/UninitializedParent.java b/jdk/test/java/lang/ClassLoader/UninitializedParent.java new file mode 100644 index 00000000000..155ae179bed --- /dev/null +++ b/jdk/test/java/lang/ClassLoader/UninitializedParent.java @@ -0,0 +1,68 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6636650 + * @summary Uninitialized class loaders should not be a parent of other + * class loaders. + */ + + +import java.net.*; + +public class UninitializedParent { + private static ClassLoader loader; + public static void main(String[] args) throws Exception { + System.setSecurityManager(new SecurityManager()); + + // Create an uninitialized class loader + try { + new ClassLoader(null) { + @Override + protected void finalize() { + loader = this; + } + }; + } catch (SecurityException exc) { + // Expected + } + System.gc(); + System.runFinalization(); + + // if 'loader' isn't null, need to ensure that it can't be used as + // parent + if (loader != null) { + try { + // Create a class loader with 'loader' being the parent + URLClassLoader child = URLClassLoader.newInstance + (new URL[0], loader); + throw new RuntimeException("Test Failed!"); + } catch (SecurityException se) { + System.out.println("Test Passed: Exception thrown"); + } + } else { + System.out.println("Test Passed: Loader is null"); + } + } +} From 193bae2884893e506c38e18e35b3f91ece2e22b9 Mon Sep 17 00:00:00 2001 From: Masayoshi Okutsu Date: Wed, 26 Aug 2009 17:05:15 +0900 Subject: [PATCH 006/172] 6824265: (tz) TimeZone.getTimeZone allows probing local filesystem Reviewed-by: peytoia --- .../sun/util/calendar/ZoneInfoFile.java | 76 +++++++++++-------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java index 6ada1afbbb6..52ec7099c51 100644 --- a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java +++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, 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 @@ -472,6 +472,18 @@ public class ZoneInfoFile { private static Map zoneInfoObjects = null; + private static final String ziDir; + static { + String zi = (String) AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("java.home")) + + File.separator + "lib" + File.separator + "zi"; + try { + zi = new File(zi).getCanonicalPath(); + } catch (Exception e) { + } + ziDir = zi; + } + /** * Converts the given time zone ID to a platform dependent path * name. For example, "America/Los_Angeles" is converted to @@ -576,20 +588,7 @@ public class ZoneInfoFile { return null; } - int index; - for (index = 0; index < JAVAZI_LABEL.length; index++) { - if (buf[index] != JAVAZI_LABEL[index]) { - System.err.println("ZoneInfo: wrong magic number: " + id); - return null; - } - } - - if (buf[index++] > JAVAZI_VERSION) { - System.err.println("ZoneInfo: incompatible version (" - + buf[index - 1] + "): " + id); - return null; - } - + int index = 0; int filesize = buf.length; int rawOffset = 0; int dstSavings = 0; @@ -600,6 +599,18 @@ public class ZoneInfoFile { int[] simpleTimeZoneParams = null; try { + for (index = 0; index < JAVAZI_LABEL.length; index++) { + if (buf[index] != JAVAZI_LABEL[index]) { + System.err.println("ZoneInfo: wrong magic number: " + id); + return null; + } + } + if (buf[index++] > JAVAZI_VERSION) { + System.err.println("ZoneInfo: incompatible version (" + + buf[index - 1] + "): " + id); + return null; + } + while (index < filesize) { byte tag = buf[index++]; int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); @@ -1017,30 +1028,33 @@ public class ZoneInfoFile { * Reads the specified file under <java.home>/lib/zi into a buffer. * @return the buffer, or null if any I/O error occurred. */ - private static byte[] readZoneInfoFile(String fileName) { + private static byte[] readZoneInfoFile(final String fileName) { byte[] buffer = null; try { - String homeDir = AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("java.home")); - final String fname = homeDir + File.separator + "lib" + File.separator - + "zi" + File.separator + fileName; buffer = (byte[]) AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws IOException { - File file = new File(fname); - if (!file.canRead()) { + File file = new File(ziDir, fileName); + if (!file.exists() || !file.isFile()) { return null; } - int filesize = (int)file.length(); - byte[] buf = new byte[filesize]; - - FileInputStream fis = new FileInputStream(file); - - if (fis.read(buf) != filesize) { - fis.close(); - throw new IOException("read error on " + fname); + file = file.getCanonicalFile(); + String path = file.getCanonicalPath(); + byte[] buf = null; + if (path != null && path.startsWith(ziDir)) { + int filesize = (int)file.length(); + if (filesize > 0) { + FileInputStream fis = new FileInputStream(file); + buf = new byte[filesize]; + try { + if (fis.read(buf) != filesize) { + throw new IOException("read error on " + fileName); + } + } finally { + fis.close(); + } + } } - fis.close(); return buf; } }); From 63810a5c4292cd5f18ca5eea9600d20becd009f5 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 3 Sep 2009 19:42:27 +0400 Subject: [PATCH 007/172] 6657026: Numerous static security flaws in Swing (findbugs) Reviewed-by: hawtin, peterz --- .../classes/javax/swing/ToolTipManager.java | 15 +- .../share/classes/javax/swing/UIManager.java | 38 +-- .../swing/plaf/basic/BasicSplitPaneUI.java | 10 +- .../javax/swing/plaf/metal/MetalBumps.java | 62 ++--- .../plaf/metal/MetalInternalFrameUI.java | 10 +- .../javax/swing/plaf/metal/MetalSliderUI.java | 23 +- .../swing/ToolTipManager/Test6657026.java | 74 ++++++ .../javax/swing/UIManager/Test6657026.java | 59 +++++ .../basic/BasicSplitPaneUI/Test6657026.java | 82 ++++++ .../plaf/metal/MetalBorders/Test6657026.java | 91 +++++++ .../plaf/metal/MetalBumps/Test6657026.java | 238 ++++++++++++++++++ .../MetalInternalFrameUI/Test6657026.java | 60 +++++ .../plaf/metal/MetalSliderUI/Test6657026.java | 67 +++++ 13 files changed, 734 insertions(+), 95 deletions(-) create mode 100644 jdk/test/javax/swing/ToolTipManager/Test6657026.java create mode 100644 jdk/test/javax/swing/UIManager/Test6657026.java create mode 100644 jdk/test/javax/swing/plaf/basic/BasicSplitPaneUI/Test6657026.java create mode 100644 jdk/test/javax/swing/plaf/metal/MetalBorders/Test6657026.java create mode 100644 jdk/test/javax/swing/plaf/metal/MetalBumps/Test6657026.java create mode 100644 jdk/test/javax/swing/plaf/metal/MetalInternalFrameUI/Test6657026.java create mode 100644 jdk/test/javax/swing/plaf/metal/MetalSliderUI/Test6657026.java diff --git a/jdk/src/share/classes/javax/swing/ToolTipManager.java b/jdk/src/share/classes/javax/swing/ToolTipManager.java index 6ee279bff36..63258349a47 100644 --- a/jdk/src/share/classes/javax/swing/ToolTipManager.java +++ b/jdk/src/share/classes/javax/swing/ToolTipManager.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, 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 @@ -27,10 +27,7 @@ package javax.swing; import java.awt.event.*; -import java.applet.*; import java.awt.*; -import java.io.Serializable; -import sun.swing.UIAction; /** * Manages all the ToolTips in the system. @@ -60,7 +57,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener JComponent insideComponent; MouseEvent mouseEvent; boolean showImmediately; - final static ToolTipManager sharedInstance = new ToolTipManager(); + private static final Object TOOL_TIP_MANAGER_KEY = new Object(); transient Popup tipWindow; /** The Window tip is being displayed in. This will be non-null if * the Window tip is in differs from that of insideComponent's Window. @@ -345,7 +342,13 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener * @return a shared ToolTipManager object */ public static ToolTipManager sharedInstance() { - return sharedInstance; + Object value = SwingUtilities.appContextGet(TOOL_TIP_MANAGER_KEY); + if (value instanceof ToolTipManager) { + return (ToolTipManager) value; + } + ToolTipManager manager = new ToolTipManager(); + SwingUtilities.appContextPut(TOOL_TIP_MANAGER_KEY, manager); + return manager; } // add keylistener here to trigger tip for access diff --git a/jdk/src/share/classes/javax/swing/UIManager.java b/jdk/src/share/classes/javax/swing/UIManager.java index e4c7c7c687d..4dee6f3198a 100644 --- a/jdk/src/share/classes/javax/swing/UIManager.java +++ b/jdk/src/share/classes/javax/swing/UIManager.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, 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 @@ -197,6 +197,8 @@ public class UIManager implements Serializable Vector auxLookAndFeels = null; SwingPropertyChangeSupport changeSupport; + LookAndFeelInfo[] installedLAFs; + UIDefaults getLookAndFeelDefaults() { return tables[0]; } void setLookAndFeelDefaults(UIDefaults x) { tables[0] = x; } @@ -227,18 +229,6 @@ public class UIManager implements Serializable */ private static final Object classLock = new Object(); - - /* Cache the last referenced LAFState to improve performance - * when accessing it. The cache is based on last thread rather - * than last AppContext because of the cost of looking up the - * AppContext each time. Since most Swing UI work is on the - * EventDispatchThread, this hits often enough to justify the - * overhead. (4193032) - */ - private static Thread currentLAFStateThread = null; - private static LAFState currentLAFState = null; - - /** * Return the LAFState object, lazily create one if necessary. * All access to the LAFState fields is done via this method, @@ -248,13 +238,6 @@ public class UIManager implements Serializable * */ private static LAFState getLAFState() { - // First check whether we're running on the same thread as - // the last request. - Thread thisThread = Thread.currentThread(); - if (thisThread == currentLAFStateThread) { - return currentLAFState; - } - LAFState rv = (LAFState)SwingUtilities.appContextGet( SwingUtilities2.LAF_STATE_KEY); if (rv == null) { @@ -268,10 +251,6 @@ public class UIManager implements Serializable } } } - - currentLAFStateThread = thisThread; - currentLAFState = rv; - return rv; } @@ -431,7 +410,10 @@ public class UIManager implements Serializable */ public static LookAndFeelInfo[] getInstalledLookAndFeels() { maybeInitialize(); - LookAndFeelInfo[] ilafs = installedLAFs; + LookAndFeelInfo[] ilafs = getLAFState().installedLAFs; + if (ilafs == null) { + ilafs = installedLAFs; + } LookAndFeelInfo[] rv = new LookAndFeelInfo[ilafs.length]; System.arraycopy(ilafs, 0, rv, 0, ilafs.length); return rv; @@ -453,9 +435,10 @@ public class UIManager implements Serializable public static void setInstalledLookAndFeels(LookAndFeelInfo[] infos) throws SecurityException { + maybeInitialize(); LookAndFeelInfo[] newInfos = new LookAndFeelInfo[infos.length]; System.arraycopy(infos, 0, newInfos, 0, infos.length); - installedLAFs = newInfos; + getLAFState().installedLAFs = newInfos; } @@ -1307,10 +1290,11 @@ public class UIManager implements Serializable } } - installedLAFs = new LookAndFeelInfo[ilafs.size()]; + LookAndFeelInfo[] installedLAFs = new LookAndFeelInfo[ilafs.size()]; for(int i = 0; i < ilafs.size(); i++) { installedLAFs[i] = ilafs.elementAt(i); } + getLAFState().installedLAFs = installedLAFs; } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java index b35a75ed700..0be46948712 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, 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 @@ -31,14 +31,12 @@ import sun.swing.DefaultLookup; import sun.swing.UIAction; import javax.swing.*; import javax.swing.border.Border; -import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.awt.peer.ComponentPeer; import java.awt.peer.LightweightPeer; import java.beans.*; import java.util.*; -import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.SplitPaneUI; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; @@ -106,13 +104,13 @@ public class BasicSplitPaneUI extends SplitPaneUI * Keys to use for forward focus traversal when the JComponent is * managing focus. */ - private static Set managingFocusForwardTraversalKeys; + private Set managingFocusForwardTraversalKeys; /** * Keys to use for backward focus traversal when the JComponent is * managing focus. */ - private static Set managingFocusBackwardTraversalKeys; + private Set managingFocusBackwardTraversalKeys; /** @@ -675,7 +673,7 @@ public class BasicSplitPaneUI extends SplitPaneUI * @return increment via keyboard methods. */ int getKeyboardMoveIncrement() { - return KEYBOARD_DIVIDER_MOVE_OFFSET; + return 3; } /** diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java index 655393b43fd..ae3ad679121 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalBumps.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 Sun Microsystems, 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 @@ -28,8 +28,9 @@ package javax.swing.plaf.metal; import java.awt.*; import java.awt.image.*; import javax.swing.*; -import java.io.*; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import sun.awt.AppContext; /** * Implements the bumps used throughout the Metal Look and Feel. @@ -49,19 +50,9 @@ class MetalBumps implements Icon { protected Color shadowColor; protected Color backColor; - protected static Vector buffers = new Vector(); + private static final Object METAL_BUMPS = new Object(); protected BumpBuffer buffer; - public MetalBumps( Dimension bumpArea ) { - this( bumpArea.width, bumpArea.height ); - } - - public MetalBumps( int width, int height ) { - this(width, height, MetalLookAndFeel.getPrimaryControlHighlight(), - MetalLookAndFeel.getPrimaryControlDarkShadow(), - MetalLookAndFeel.getPrimaryControlShadow()); - } - /** * Creates MetalBumps of the specified size with the specified colors. * If newBackColor is null, the background will be @@ -73,26 +64,22 @@ class MetalBumps implements Icon { setBumpColors( newTopColor, newShadowColor, newBackColor ); } - private BumpBuffer getBuffer(GraphicsConfiguration gc, Color aTopColor, - Color aShadowColor, Color aBackColor) { - if (buffer != null && buffer.hasSameConfiguration( - gc, aTopColor, aShadowColor, aBackColor)) { - return buffer; + private static BumpBuffer createBuffer(GraphicsConfiguration gc, + Color topColor, Color shadowColor, Color backColor) { + AppContext context = AppContext.getAppContext(); + List buffers = (List) context.get(METAL_BUMPS); + if (buffers == null) { + buffers = new ArrayList(); + context.put(METAL_BUMPS, buffers); } - BumpBuffer result = null; - - for (BumpBuffer aBuffer : buffers) { - if ( aBuffer.hasSameConfiguration(gc, aTopColor, aShadowColor, - aBackColor)) { - result = aBuffer; - break; + for (BumpBuffer buffer : buffers) { + if (buffer.hasSameConfiguration(gc, topColor, shadowColor, backColor)) { + return buffer; } } - if (result == null) { - result = new BumpBuffer(gc, topColor, shadowColor, backColor); - buffers.addElement(result); - } - return result; + BumpBuffer buffer = new BumpBuffer(gc, topColor, shadowColor, backColor); + buffers.add(buffer); + return buffer; } public void setBumpArea( Dimension bumpArea ) { @@ -119,10 +106,12 @@ class MetalBumps implements Icon { GraphicsConfiguration gc = (g instanceof Graphics2D) ? ((Graphics2D) g).getDeviceConfiguration() : null; - buffer = getBuffer(gc, topColor, shadowColor, backColor); + if ((buffer == null) || !buffer.hasSameConfiguration(gc, topColor, shadowColor, backColor)) { + buffer = createBuffer(gc, topColor, shadowColor, backColor); + } - int bufferWidth = buffer.getImageSize().width; - int bufferHeight = buffer.getImageSize().height; + int bufferWidth = BumpBuffer.IMAGE_SIZE; + int bufferHeight = BumpBuffer.IMAGE_SIZE; int iconWidth = getIconWidth(); int iconHeight = getIconHeight(); int x2 = x + iconWidth; @@ -155,7 +144,6 @@ class MetalBumps implements Icon { class BumpBuffer { static final int IMAGE_SIZE = 64; - static Dimension imageSize = new Dimension( IMAGE_SIZE, IMAGE_SIZE ); transient Image image; Color topColor; @@ -197,10 +185,6 @@ class BumpBuffer { return image; } - public Dimension getImageSize() { - return imageSize; - } - /** * Paints the bumps into the current image. */ diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameUI.java index d960ca19b75..adac940c4a4 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalInternalFrameUI.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 Sun Microsystems, 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 @@ -31,10 +31,8 @@ import javax.swing.*; import javax.swing.event.*; import javax.swing.border.*; import javax.swing.plaf.basic.*; -import java.util.EventListener; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; -import java.beans.PropertyVetoException; import javax.swing.plaf.*; /** @@ -51,7 +49,7 @@ public class MetalInternalFrameUI extends BasicInternalFrameUI { private static final Border handyEmptyBorder = new EmptyBorder(0,0,0,0); protected static String IS_PALETTE = "JInternalFrame.isPalette"; - + private static String IS_PALETTE_KEY = "JInternalFrame.isPalette"; private static String FRAME_TYPE = "JInternalFrame.frameType"; private static String NORMAL_FRAME = "normal"; private static String PALETTE_FRAME = "palette"; @@ -68,7 +66,7 @@ public class MetalInternalFrameUI extends BasicInternalFrameUI { public void installUI(JComponent c) { super.installUI(c); - Object paletteProp = c.getClientProperty( IS_PALETTE ); + Object paletteProp = c.getClientProperty(IS_PALETTE_KEY); if ( paletteProp != null ) { setPalette( ((Boolean)paletteProp).booleanValue() ); } @@ -187,7 +185,7 @@ public class MetalInternalFrameUI extends BasicInternalFrameUI { ui.setFrameType( (String) e.getNewValue() ); } } - else if ( name.equals( IS_PALETTE ) ) + else if ( name.equals(IS_PALETTE_KEY) ) { if ( e.getNewValue() != null ) { diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java index 28d22705b16..da3d424e409 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalSliderUI.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 Sun Microsystems, 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 @@ -54,12 +54,13 @@ public class MetalSliderUI extends BasicSliderUI { protected final int TICK_BUFFER = 4; protected boolean filledSlider = false; - // NOTE: these next three variables are currently unused. + // NOTE: these next five variables are currently unused. protected static Color thumbColor; protected static Color highlightColor; protected static Color darkShadowColor; protected static int trackWidth; protected static int tickLength; + private int safeLength; /** * A default horizontal thumb Icon. This field might not be @@ -107,7 +108,7 @@ public class MetalSliderUI extends BasicSliderUI { public void installUI( JComponent c ) { trackWidth = ((Integer)UIManager.get( "Slider.trackWidth" )).intValue(); - tickLength = ((Integer)UIManager.get( "Slider.majorTickLength" )).intValue(); + tickLength = safeLength = ((Integer)UIManager.get( "Slider.majorTickLength" )).intValue(); horizThumbIcon = SAFE_HORIZ_THUMB_ICON = UIManager.getIcon( "Slider.horizontalThumbIcon" ); vertThumbIcon = SAFE_VERT_THUMB_ICON = @@ -477,8 +478,8 @@ public class MetalSliderUI extends BasicSliderUI { * determine the tick area rectangle. */ public int getTickLength() { - return slider.getOrientation() == JSlider.HORIZONTAL ? tickLength + TICK_BUFFER + 1 : - tickLength + TICK_BUFFER + 3; + return slider.getOrientation() == JSlider.HORIZONTAL ? safeLength + TICK_BUFFER + 1 : + safeLength + TICK_BUFFER + 3; } /** @@ -523,22 +524,22 @@ public class MetalSliderUI extends BasicSliderUI { protected void paintMinorTickForHorizSlider( Graphics g, Rectangle tickBounds, int x ) { g.setColor( slider.isEnabled() ? slider.getForeground() : MetalLookAndFeel.getControlShadow() ); - g.drawLine( x, TICK_BUFFER, x, TICK_BUFFER + (tickLength / 2) ); + g.drawLine( x, TICK_BUFFER, x, TICK_BUFFER + (safeLength / 2) ); } protected void paintMajorTickForHorizSlider( Graphics g, Rectangle tickBounds, int x ) { g.setColor( slider.isEnabled() ? slider.getForeground() : MetalLookAndFeel.getControlShadow() ); - g.drawLine( x, TICK_BUFFER , x, TICK_BUFFER + (tickLength - 1) ); + g.drawLine( x, TICK_BUFFER , x, TICK_BUFFER + (safeLength - 1) ); } protected void paintMinorTickForVertSlider( Graphics g, Rectangle tickBounds, int y ) { g.setColor( slider.isEnabled() ? slider.getForeground() : MetalLookAndFeel.getControlShadow() ); if (MetalUtils.isLeftToRight(slider)) { - g.drawLine( TICK_BUFFER, y, TICK_BUFFER + (tickLength / 2), y ); + g.drawLine( TICK_BUFFER, y, TICK_BUFFER + (safeLength / 2), y ); } else { - g.drawLine( 0, y, tickLength/2, y ); + g.drawLine( 0, y, safeLength/2, y ); } } @@ -546,10 +547,10 @@ public class MetalSliderUI extends BasicSliderUI { g.setColor( slider.isEnabled() ? slider.getForeground() : MetalLookAndFeel.getControlShadow() ); if (MetalUtils.isLeftToRight(slider)) { - g.drawLine( TICK_BUFFER, y, TICK_BUFFER + tickLength, y ); + g.drawLine( TICK_BUFFER, y, TICK_BUFFER + safeLength, y ); } else { - g.drawLine( 0, y, tickLength, y ); + g.drawLine( 0, y, safeLength, y ); } } } diff --git a/jdk/test/javax/swing/ToolTipManager/Test6657026.java b/jdk/test/javax/swing/ToolTipManager/Test6657026.java new file mode 100644 index 00000000000..f9e23b988bb --- /dev/null +++ b/jdk/test/javax/swing/ToolTipManager/Test6657026.java @@ -0,0 +1,74 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6657026 + * @summary Tests shared ToolTipManager in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; +import javax.swing.ToolTipManager; + +public class Test6657026 implements Runnable { + + private static final int DISMISS = 4000; + private static final int INITIAL = 750; + private static final int RESHOW = 500; + + public static void main(String[] args) throws InterruptedException { + ToolTipManager manager = ToolTipManager.sharedInstance(); + if (DISMISS != manager.getDismissDelay()) { + throw new Error("unexpected dismiss delay"); + } + if (INITIAL != manager.getInitialDelay()) { + throw new Error("unexpected initial delay"); + } + if (RESHOW != manager.getReshowDelay()) { + throw new Error("unexpected reshow delay"); + } + manager.setDismissDelay(DISMISS + 1); + manager.setInitialDelay(INITIAL + 1); + manager.setReshowDelay(RESHOW + 1); + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + } + + public void run() { + SunToolkit.createNewAppContext(); + ToolTipManager manager = ToolTipManager.sharedInstance(); + if (DISMISS != manager.getDismissDelay()) { + throw new Error("shared dismiss delay"); + } + if (INITIAL != manager.getInitialDelay()) { + throw new Error("shared initial delay"); + } + if (RESHOW != manager.getReshowDelay()) { + throw new Error("shared reshow delay"); + } + } +} diff --git a/jdk/test/javax/swing/UIManager/Test6657026.java b/jdk/test/javax/swing/UIManager/Test6657026.java new file mode 100644 index 00000000000..7b93a22196c --- /dev/null +++ b/jdk/test/javax/swing/UIManager/Test6657026.java @@ -0,0 +1,59 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6657026 + * @summary Tests shared UIManager in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; + +public class Test6657026 implements Runnable { + + public static void main(String[] args) throws Exception { + if (UIManager.getInstalledLookAndFeels().length == 0) { + throw new Error("unexpected amount of look&feels"); + } + UIManager.setInstalledLookAndFeels(new LookAndFeelInfo[0]); + if (UIManager.getInstalledLookAndFeels().length != 0) { + throw new Error("unexpected amount of look&feels"); + } + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + } + + public void run() { + SunToolkit.createNewAppContext(); + if (UIManager.getInstalledLookAndFeels().length == 0) { + throw new Error("shared look&feels"); + } + } +} diff --git a/jdk/test/javax/swing/plaf/basic/BasicSplitPaneUI/Test6657026.java b/jdk/test/javax/swing/plaf/basic/BasicSplitPaneUI/Test6657026.java new file mode 100644 index 00000000000..16080416f73 --- /dev/null +++ b/jdk/test/javax/swing/plaf/basic/BasicSplitPaneUI/Test6657026.java @@ -0,0 +1,82 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6657026 + * @summary Tests shared BasicSplitPaneUI in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import java.awt.event.ActionEvent; +import java.util.Set; +import javax.swing.JSplitPane; +import javax.swing.plaf.basic.BasicSplitPaneUI; + +public class Test6657026 extends BasicSplitPaneUI implements Runnable { + + public static void main(String[] args) throws InterruptedException { + if (new JSplitPane().getFocusTraversalKeys(0).isEmpty()){ + throw new Error("unexpected traversal keys"); + } + new JSplitPane() { + public void setFocusTraversalKeys(int id, Set keystrokes) { + keystrokes.clear(); + super.setFocusTraversalKeys(id, keystrokes); + } + }; + if (new JSplitPane().getFocusTraversalKeys(0).isEmpty()) { + throw new Error("shared traversal keys"); + } + KEYBOARD_DIVIDER_MOVE_OFFSET = -KEYBOARD_DIVIDER_MOVE_OFFSET; + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + } + + public void run() { + SunToolkit.createNewAppContext(); + if (new JSplitPane().getFocusTraversalKeys(0).isEmpty()) { + throw new Error("shared traversal keys"); + } + JSplitPane pane = new JSplitPane(); + pane.setUI(this); + + createFocusListener().focusGained(null); // allows actions + test(pane, "positiveIncrement", 3); + test(pane, "negativeIncrement", 0); + } + + private static void test(JSplitPane pane, String action, int expected) { + ActionEvent event = new ActionEvent(pane, expected, action); + pane.getActionMap().get(action).actionPerformed(event); + int actual = pane.getDividerLocation(); + if (actual != expected) { + throw new Error(actual + ", but expected " + expected); + } + } +} diff --git a/jdk/test/javax/swing/plaf/metal/MetalBorders/Test6657026.java b/jdk/test/javax/swing/plaf/metal/MetalBorders/Test6657026.java new file mode 100644 index 00000000000..194b310f450 --- /dev/null +++ b/jdk/test/javax/swing/plaf/metal/MetalBorders/Test6657026.java @@ -0,0 +1,91 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6657026 + * @summary Tests constancy of borders + * @author Sergey Malenkov + */ + +import java.awt.Insets; +import javax.swing.border.Border; +import javax.swing.plaf.metal.MetalBorders.ButtonBorder; +import javax.swing.plaf.metal.MetalBorders.MenuBarBorder; +import javax.swing.plaf.metal.MetalBorders.MenuItemBorder; +import javax.swing.plaf.metal.MetalBorders.PopupMenuBorder; + +public class Test6657026 { + + private static final Insets NEGATIVE = new Insets(Integer.MIN_VALUE, + Integer.MIN_VALUE, + Integer.MIN_VALUE, + Integer.MIN_VALUE); + + public static void main(String[] args) { + new ButtonBorder() {{borderInsets = NEGATIVE;}}; + new MenuBarBorder() {{borderInsets = NEGATIVE;}}; + new MenuItemBorder() {{borderInsets = NEGATIVE;}}; + new PopupMenuBorder() {{borderInsets = NEGATIVE;}}; + + test(create("ButtonBorder")); + test(create("MenuBarBorder")); + test(create("MenuItemBorder")); + test(create("PopupMenuBorder")); + + test(create("Flush3DBorder")); + test(create("InternalFrameBorder")); + // NOT USED: test(create("FrameBorder")); + // NOT USED: test(create("DialogBorder")); + test(create("PaletteBorder")); + test(create("OptionDialogBorder")); + test(create("ScrollPaneBorder")); + } + + private static Border create(String name) { + try { + name = "javax.swing.plaf.metal.MetalBorders$" + name; + return (Border) Class.forName(name).newInstance(); + } + catch (Exception exception) { + throw new Error("unexpected exception", exception); + } + } + + private static void test(Border border) { + Insets actual = border.getBorderInsets(null); + if (NEGATIVE.equals(actual)) { + throw new Error("unexpected insets in " + border.getClass()); + } + Insets expected = (Insets) actual.clone(); + // modify + actual.top++; + actual.left++; + actual.right++; + actual.bottom++; + // validate + if (!expected.equals(border.getBorderInsets(null))) { + throw new Error("shared insets in " + border.getClass()); + } + } +} diff --git a/jdk/test/javax/swing/plaf/metal/MetalBumps/Test6657026.java b/jdk/test/javax/swing/plaf/metal/MetalBumps/Test6657026.java new file mode 100644 index 00000000000..f8041629346 --- /dev/null +++ b/jdk/test/javax/swing/plaf/metal/MetalBumps/Test6657026.java @@ -0,0 +1,238 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6657026 + * @summary Tests shared MetalBumps in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.text.AttributedCharacterIterator; +import javax.swing.Icon; +import javax.swing.plaf.metal.MetalBorders.ToolBarBorder; + +public class Test6657026 extends ToolBarBorder implements Runnable { + + public static void main(String[] args) throws Exception { + new Test6657026().test(); + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + } + + public void run() { + SunToolkit.createNewAppContext(); + test(); + } + + private void test() { + MyGraphics mg = new MyGraphics(); + Icon icon = bumps; + icon.paintIcon(mg.component, mg, 0, 0); + if (mg.image != null) { + boolean failed = true; + int value = mg.image.getRGB(0, 0); + for (int x = 0; x < mg.image.getWidth(); x++) { + for (int y = 0; y < mg.image.getHeight(); y++) { + int current = mg.image.getRGB(x, y); + if (current != value) { + mg.image.setRGB(x, y, value); + failed = false; + } + + } + } + if (failed) { + throw new Error("shared metal bumps"); + } + } + } + + private static class MyGraphics extends Graphics { + + private final Component component = new Component() {}; + private BufferedImage image; + + public Graphics create() { + return null; // TODO: check + } + + public void translate(int x, int y) { + // TODO: check + } + + public Color getColor() { + return null; // TODO: check + } + + public void setColor(Color color) { + // TODO: check + } + + public void setPaintMode() { + // TODO: check + } + + public void setXORMode(Color c1) { + // TODO: check + } + + public Font getFont() { + return null; // TODO: check + } + + public void setFont(Font font) { + // TODO: check + } + + public FontMetrics getFontMetrics(Font font) { + return null; // TODO: check + } + + public Rectangle getClipBounds() { + return null; // TODO: check + } + + public void clipRect(int x, int y, int width, int height) { + // TODO: check + } + + public void setClip(int x, int y, int width, int height) { + // TODO: check + } + + public Shape getClip() { + return null; // TODO: check + } + + public void setClip(Shape clip) { + // TODO: check + } + + public void copyArea(int x, int y, int width, int height, int dx, int dy) { + // TODO: check + } + + public void drawLine(int x1, int y1, int x2, int y2) { + // TODO: check + } + + public void fillRect(int x, int y, int width, int height) { + // TODO: check + } + + public void clearRect(int x, int y, int width, int height) { + // TODO: check + } + + public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { + // TODO: check + } + + public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { + // TODO: check + } + + public void drawOval(int x, int y, int width, int height) { + // TODO: check + } + + public void fillOval(int x, int y, int width, int height) { + // TODO: check + } + + public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { + // TODO: check + } + + public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { + // TODO: check + } + + public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { + // TODO: check + } + + public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { + // TODO: check + } + + public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { + // TODO: check + } + + public void drawString(String str, int x, int y) { + // TODO: check + } + + public void drawString(AttributedCharacterIterator iterator, int x, int y) { + // TODO: check + } + + public boolean drawImage(Image img, int x, int y, ImageObserver observer) { + return false; // TODO: check + } + + public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { + return false; // TODO: check + } + + public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { + return false; // TODO: check + } + + public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) { + return false; // TODO: check + } + + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { + if (img instanceof BufferedImage) { + this.image = (BufferedImage) img; + } + return false; // TODO: check + } + + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) { + return false; // TODO: check + } + + public void dispose() { + // TODO: check + } + } +} diff --git a/jdk/test/javax/swing/plaf/metal/MetalInternalFrameUI/Test6657026.java b/jdk/test/javax/swing/plaf/metal/MetalInternalFrameUI/Test6657026.java new file mode 100644 index 00000000000..bbfec61c5ba --- /dev/null +++ b/jdk/test/javax/swing/plaf/metal/MetalInternalFrameUI/Test6657026.java @@ -0,0 +1,60 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6657026 + * @summary Tests shared MetalInternalFrameUI in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import javax.swing.JInternalFrame; +import javax.swing.JPanel; +import javax.swing.UIManager; +import javax.swing.plaf.metal.MetalInternalFrameUI; +import javax.swing.plaf.metal.MetalLookAndFeel; + +public class Test6657026 extends MetalInternalFrameUI implements Runnable { + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel(new MetalLookAndFeel()); + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + + new JInternalFrame().setContentPane(new JPanel()); + } + + public Test6657026() { + super(null); + } + + public void run() { + SunToolkit.createNewAppContext(); + IS_PALETTE = JInternalFrame.CONTENT_PANE_PROPERTY; + } +} diff --git a/jdk/test/javax/swing/plaf/metal/MetalSliderUI/Test6657026.java b/jdk/test/javax/swing/plaf/metal/MetalSliderUI/Test6657026.java new file mode 100644 index 00000000000..250889acd89 --- /dev/null +++ b/jdk/test/javax/swing/plaf/metal/MetalSliderUI/Test6657026.java @@ -0,0 +1,67 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6657026 + * @summary Tests shared MetalSliderUI in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import javax.swing.JSlider; +import javax.swing.UIManager; +import javax.swing.plaf.metal.MetalLookAndFeel; +import javax.swing.plaf.metal.MetalSliderUI; + +public class Test6657026 extends MetalSliderUI implements Runnable { + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel(new MetalLookAndFeel()); + JSlider slider = new JSlider(); + test(slider); + + ThreadGroup group = new ThreadGroup("$$$"); + Thread thread = new Thread(group, new Test6657026()); + thread.start(); + thread.join(); + + test(slider); + } + + public void run() { + SunToolkit.createNewAppContext(); + JSlider slider = new JSlider(); + test(slider); + tickLength = -10000; + } + + private static void test(JSlider slider) { + MetalSliderUI ui = (MetalSliderUI) slider.getUI(); + int actual = ui.getTickLength(); + if (actual != 11) { + throw new Error(actual + ", but expected 11"); + } + } +} From 67e3ba76c16c6888439ae4bd4874c83957b92ae9 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Thu, 10 Sep 2009 12:26:34 +0400 Subject: [PATCH 008/172] 6874643: ImageI/O JPEG is vulnerable to Heap Overflow Reviewed-by: prr, hawtin --- jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c index 7d39c61e02f..448232143ae 100644 --- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c +++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c @@ -1833,6 +1833,13 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage return JNI_FALSE; } + if (stepX > cinfo->image_width) { + stepX = cinfo->image_width; + } + if (stepY > cinfo->image_height) { + stepY = cinfo->image_height; + } + /* * First get the source bands array and copy it to our local array * so we don't have to worry about pinning and unpinning it again. From a3de8d40ebe6a8403a0b26189e8df2fe2931acbf Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Thu, 10 Sep 2009 12:50:09 +0400 Subject: [PATCH 009/172] 6872357: JRE AWT setDifflCM vulnerable to Stack Overflow Reviewed-by: prr, hawtin --- jdk/src/share/native/sun/awt/image/awt_ImageRep.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jdk/src/share/native/sun/awt/image/awt_ImageRep.c b/jdk/src/share/native/sun/awt/image/awt_ImageRep.c index 9017ee9520f..79975ff7a35 100644 --- a/jdk/src/share/native/sun/awt/image/awt_ImageRep.c +++ b/jdk/src/share/native/sun/awt/image/awt_ImageRep.c @@ -266,6 +266,13 @@ Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls, jnewlut = (*env)->GetObjectField(env, jicm, g_ICMrgbID); mapSize = (*env)->GetIntField(env, jicm, g_ICMmapSizeID); + if (numLut < 0 || numLut > 256 || mapSize < 0 || mapSize > 256) { + /* Ether old or new ICM has a palette that exceeds capacity + of byte data type, so we have to convert the image data + to default representation. + */ + return 0; + } srcLUT = (unsigned int *) (*env)->GetPrimitiveArrayCritical(env, jlut, NULL); if (srcLUT == NULL) { From e07c626a488297ee24b91812ce71867c4d42de8e Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Thu, 10 Sep 2009 13:35:28 +0400 Subject: [PATCH 010/172] 6862968: JPEG Image Writer quantization problem Reviewed-by: prr, hawtin --- .../native/sun/awt/image/jpeg/imageioJPEG.c | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c index 448232143ae..3897ddc86c6 100644 --- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c +++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c @@ -676,6 +676,10 @@ static int setQTables(JNIEnv *env, #ifdef DEBUG_IIO_JPEG printf("in setQTables, qlen = %d, write is %d\n", qlen, write); #endif + if (qlen > NUM_QUANT_TBLS) { + /* Ignore extra qunterization tables. */ + qlen = NUM_QUANT_TBLS; + } for (i = 0; i < qlen; i++) { table = (*env)->GetObjectArrayElement(env, qtables, i); qdata = (*env)->GetObjectField(env, table, JPEGQTable_tableID); @@ -727,6 +731,11 @@ static void setHuffTable(JNIEnv *env, hlensBody = (*env)->GetShortArrayElements(env, huffLens, NULL); + if (hlensLen > 16) { + /* Ignore extra elements of bits array. Only 16 elements can be + stored. 0-th element is not used. (see jpeglib.h, line 107) */ + hlensLen = 16; + } for (i = 1; i <= hlensLen; i++) { huff_ptr->bits[i] = (UINT8)hlensBody[i-1]; } @@ -743,6 +752,11 @@ static void setHuffTable(JNIEnv *env, huffValues, NULL); + if (hvalsLen > 256) { + /* Ignore extra elements of hufval array. Only 256 elements + can be stored. (see jpeglib.h, line 109) */ + hlensLen = 256; + } for (i = 0; i < hvalsLen; i++) { huff_ptr->huffval[i] = (UINT8)hvalsBody[i]; } @@ -763,6 +777,11 @@ static int setHTables(JNIEnv *env, j_compress_ptr comp; j_decompress_ptr decomp; jsize hlen = (*env)->GetArrayLength(env, DCHuffmanTables); + + if (hlen > NUM_HUFF_TBLS) { + /* Ignore extra DC huffman tables. */ + hlen = NUM_HUFF_TBLS; + } for (i = 0; i < hlen; i++) { if (cinfo->is_decompressor) { decomp = (j_decompress_ptr) cinfo; @@ -784,6 +803,10 @@ static int setHTables(JNIEnv *env, huff_ptr->sent_table = !write; } hlen = (*env)->GetArrayLength(env, ACHuffmanTables); + if (hlen > NUM_HUFF_TBLS) { + /* Ignore extra AC huffman tables. */ + hlen = NUM_HUFF_TBLS; + } for (i = 0; i < hlen; i++) { if (cinfo->is_decompressor) { decomp = (j_decompress_ptr) cinfo; From c26aec2e526846e29966f380af93dbae9a5d1c3d Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Thu, 10 Sep 2009 13:52:27 +0400 Subject: [PATCH 011/172] 6822057: X11 and Win32GraphicsDevice don't clone arrays returned from getConfigurations() Reviewed-by: prr, hawtin --- .../classes/sun/awt/X11GraphicsDevice.java | 2 +- .../classes/sun/awt/Win32GraphicsDevice.java | 4 +- .../sun/java2d/d3d/D3DGraphicsDevice.java | 2 +- .../awt/GraphicsDevice/CloneConfigsTest.java | 118 ++++++++++++++++++ 4 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 jdk/test/java/awt/GraphicsDevice/CloneConfigsTest.java diff --git a/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java b/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java index ed495b177ec..81491abeea3 100644 --- a/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java +++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java @@ -134,7 +134,7 @@ public class X11GraphicsDevice makeConfigurations(); } } - return configs; + return configs.clone(); } private void makeConfigurations() { diff --git a/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java b/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java index 1da339ce9f1..8a0960bc6d8 100644 --- a/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java +++ b/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java @@ -165,7 +165,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements if (defaultConfig != null) { configs = new GraphicsConfiguration[1]; configs[0] = defaultConfig; - return configs; + return configs.clone(); } } @@ -196,7 +196,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements configs = new GraphicsConfiguration[v.size()]; v.copyInto(configs); } - return configs; + return configs.clone(); } /** diff --git a/jdk/src/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java b/jdk/src/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java index a4334b42f12..30f076a4f91 100644 --- a/jdk/src/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java +++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java @@ -426,7 +426,7 @@ public class D3DGraphicsDevice extends Win32GraphicsDevice { if (defaultConfig != null) { configs = new GraphicsConfiguration[1]; configs[0] = defaultConfig; - return configs; + return configs.clone(); } } } diff --git a/jdk/test/java/awt/GraphicsDevice/CloneConfigsTest.java b/jdk/test/java/awt/GraphicsDevice/CloneConfigsTest.java new file mode 100644 index 00000000000..44eec545dda --- /dev/null +++ b/jdk/test/java/awt/GraphicsDevice/CloneConfigsTest.java @@ -0,0 +1,118 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6822057 + * + * @summary Test verifies that list of supported graphics configurations + * can not be changed via modification of elements of an array + * returned by getConfiguration() method. + * + * @run main CloneConfigsTest + * @run main/othervm -Dsun.java2d.opengl=True CloneConfigsTest + * @run main/othervm -Dsun.java2d.d3d=true CloneConfigsTest + * @run main/othervm -Dsun.java2d.noddraw=true CloneConfigsTest + */ + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; + +public class CloneConfigsTest { + + public static void main(String[] args) { + GraphicsEnvironment env = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + + GraphicsDevice[] devices = env.getScreenDevices(); + + GraphicsConfiguration c = new TestConfig(); + + for (GraphicsDevice gd : devices) { + System.out.println("Device: " + gd); + + GraphicsConfiguration[] configs = gd.getConfigurations(); + + for (int i = 0; i < configs.length; i++) { + GraphicsConfiguration gc = configs[i]; + System.out.println("\tConfig: " + gc); + + configs[i] = c; + } + + // verify whether array of configs was modified + configs = gd.getConfigurations(); + for (GraphicsConfiguration gc : configs) { + if (gc == c) { + throw new RuntimeException("Test failed."); + } + } + System.out.println("Test passed."); + } + } + + private static class TestConfig extends GraphicsConfiguration { + + @Override + public GraphicsDevice getDevice() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BufferedImage createCompatibleImage(int width, int height) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ColorModel getColorModel() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ColorModel getColorModel(int transparency) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public AffineTransform getDefaultTransform() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public AffineTransform getNormalizingTransform() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Rectangle getBounds() { + throw new UnsupportedOperationException("Not supported yet."); + } + + } + +} From 3915dad0c75b379604411c5aeb20df42fbf19cb9 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Thu, 10 Sep 2009 14:04:38 +0400 Subject: [PATCH 012/172] 6632445: DoS from parsing BMPs with UNC ICC links Reviewed-by: prr, hawtin --- .../imageio/plugins/bmp/BMPImageReader.java | 79 ++++++++++++++++++- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java index f8e028d197b..388d7a1b6fb 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java @@ -62,6 +62,8 @@ import javax.imageio.event.IIOReadWarningListener; import java.io.*; import java.nio.*; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Iterator; import java.util.StringTokenizer; @@ -502,12 +504,18 @@ public class BMPImageReader extends ImageReader implements BMPConstants { iis.reset(); try { - if (metadata.colorSpace == PROFILE_LINKED) + if (metadata.colorSpace == PROFILE_LINKED && + isLinkedProfileAllowed() && + !isUncOrDevicePath(profile)) + { + String path = new String(profile, "windows-1252"); + colorSpace = - new ICC_ColorSpace(ICC_Profile.getInstance(new String(profile))); - else + new ICC_ColorSpace(ICC_Profile.getInstance(path)); + } else { colorSpace = new ICC_ColorSpace(ICC_Profile.getInstance(profile)); + } } catch (Exception e) { colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); } @@ -1745,4 +1753,69 @@ public class BMPImageReader extends ImageReader implements BMPConstants { public void sequenceStarted(ImageReader src, int minIndex) {} public void readAborted(ImageReader src) {} } + + private static Boolean isLinkedProfileDisabled = null; + + private static boolean isLinkedProfileAllowed() { + if (isLinkedProfileDisabled == null) { + PrivilegedAction a = new PrivilegedAction() { + public Boolean run() { + return Boolean.getBoolean("sun.imageio.plugins.bmp.disableLinkedProfiles"); + } + }; + isLinkedProfileDisabled = AccessController.doPrivileged(a); + } + return !isLinkedProfileDisabled; + } + + private static Boolean isWindowsPlatform = null; + + /** + * Verifies whether the byte array contans a unc path. + * Non-UNC path examples: + * c:\path\to\file - simple notation + * \\?\c:\path\to\file - long notation + * + * UNC path examples: + * \\server\share - a UNC path in simple notation + * \\?\UNC\server\share - a UNC path in long notation + * \\.\some\device - a path to device. + */ + private static boolean isUncOrDevicePath(byte[] p) { + if (isWindowsPlatform == null) { + PrivilegedAction a = new PrivilegedAction() { + public Boolean run() { + String osname = System.getProperty("os.name"); + return (osname != null && + osname.toLowerCase().startsWith("win")); + } + }; + isWindowsPlatform = AccessController.doPrivileged(a); + } + + if (!isWindowsPlatform) { + /* no need for the check on platforms except windows */ + return false; + } + + /* normalize prefix of the path */ + if (p[0] == '/') p[0] = '\\'; + if (p[1] == '/') p[1] = '\\'; + if (p[3] == '/') p[3] = '\\'; + + + if ((p[0] == '\\') && (p[1] == '\\')) { + if ((p[2] == '?') && (p[3] == '\\')) { + // long path: whether unc or local + return ((p[4] == 'U' || p[4] == 'u') && + (p[5] == 'N' || p[5] == 'n') && + (p[6] == 'C' || p[6] == 'c')); + } else { + // device path or short unc notation + return true; + } + } else { + return false; + } + } } From c87d132dccc80e55d0e53379381f4210da3e17bd Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Thu, 10 Sep 2009 14:15:47 +0400 Subject: [PATCH 013/172] 6631533: ICC_Profile allows detecting if some files exist Reviewed-by: prr, hawtin --- .../classes/java/awt/color/ICC_Profile.java | 158 +++++++++++------- 1 file changed, 96 insertions(+), 62 deletions(-) diff --git a/jdk/src/share/classes/java/awt/color/ICC_Profile.java b/jdk/src/share/classes/java/awt/color/ICC_Profile.java index 44f28508788..84b8a8c63d3 100644 --- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java +++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java @@ -863,7 +863,9 @@ public class ICC_Profile implements Serializable { case ColorSpace.CS_PYCC: synchronized(ICC_Profile.class) { if (PYCCprofile == null) { - if (getProfileFile("PYCC.pf") != null) { + if (!sun.jkernel.DownloadManager.isJREComplete() || + standardProfileExists("PYCC.pf")) + { ProfileDeferralInfo pInfo = new ProfileDeferralInfo("PYCC.pf", ColorSpace.TYPE_3CLR, 3, @@ -961,15 +963,15 @@ public class ICC_Profile implements Serializable { * and it does not permit read access to the given file. */ public static ICC_Profile getInstance(String fileName) throws IOException { - ICC_Profile thisProfile; - FileInputStream fis; + ICC_Profile thisProfile; + FileInputStream fis = null; - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(fileName); + + File f = getProfileFile(fileName); + if (f != null) { + fis = new FileInputStream(f); } - - if ((fis = openProfile(fileName)) == null) { + if (fis == null) { throw new IOException("Cannot open file " + fileName); } @@ -1081,11 +1083,22 @@ public class ICC_Profile implements Serializable { void activateDeferredProfile() throws ProfileDataException { byte profileData[]; FileInputStream fis; - String fileName = deferralInfo.filename; + final String fileName = deferralInfo.filename; profileActivator = null; deferralInfo = null; - if ((fis = openProfile(fileName)) == null) { + PrivilegedAction pa = new PrivilegedAction() { + public FileInputStream run() { + File f = getStandardProfileFile(fileName); + if (f != null) { + try { + return new FileInputStream(f); + } catch (FileNotFoundException e) {} + } + return null; + } + }; + if ((fis = AccessController.doPrivileged(pa)) == null) { throw new ProfileDataException("Cannot open file " + fileName); } try { @@ -1784,86 +1797,107 @@ public class ICC_Profile implements Serializable { * available, such as a profile for sRGB. Built-in profiles use .pf as * the file name extension for profiles, e.g. sRGB.pf. */ - private static FileInputStream openProfile(final String fileName) { - return (FileInputStream)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - File f = privilegedGetProfileFile(fileName); - if (f != null) { - try { - return new FileInputStream(f); - } catch (FileNotFoundException e) { - } - } - return null; - } - }); - } - - private static File getProfileFile(final String fileName) { - return (File)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - return privilegedGetProfileFile(fileName); - } - }); - } - - /* - * this version is called from doPrivileged in openProfile - * or getProfileFile, so the whole method is privileged! - */ - - private static File privilegedGetProfileFile(String fileName) { + private static File getProfileFile(String fileName) { String path, dir, fullPath; File f = new File(fileName); /* try absolute file name */ - + if (f.isAbsolute()) { + /* Rest of code has little sense for an absolute pathname, + so return here. */ + return f.isFile() ? f : null; + } if ((!f.isFile()) && ((path = System.getProperty("java.iccprofile.path")) != null)){ /* try relative to java.iccprofile.path */ StringTokenizer st = new StringTokenizer(path, File.pathSeparator); - while (st.hasMoreTokens() && (!f.isFile())) { + while (st.hasMoreTokens() && ((f == null) || (!f.isFile()))) { dir = st.nextToken(); fullPath = dir + File.separatorChar + fileName; f = new File(fullPath); + if (!isChildOf(f, dir)) { + f = null; + } } } - if ((!f.isFile()) && + if (((f == null) || (!f.isFile())) && ((path = System.getProperty("java.class.path")) != null)) { /* try relative to java.class.path */ StringTokenizer st = new StringTokenizer(path, File.pathSeparator); - while (st.hasMoreTokens() && (!f.isFile())) { + while (st.hasMoreTokens() && ((f == null) || (!f.isFile()))) { dir = st.nextToken(); fullPath = dir + File.separatorChar + fileName; f = new File(fullPath); + if (!isChildOf(f, dir)) { + f = null; + } } } - - if (!f.isFile()) { /* try the directory of built-in profiles */ - dir = System.getProperty("java.home") + - File.separatorChar + "lib" + File.separatorChar + "cmm"; - fullPath = dir + File.separatorChar + fileName; - f = new File(fullPath); - if (!f.isFile()) { - //make sure file was installed in the kernel mode - try { - //kernel uses platform independent paths => - // should not use platform separator char - sun.jkernel.DownloadManager.downloadFile("lib/cmm/"+fileName); - } catch (IOException ioe) {} - } - } - - if (f.isFile()) { + if ((f == null) || (!f.isFile())) { + /* try the directory of built-in profiles */ + f = getStandardProfileFile(fileName); + } + if (f != null && f.isFile()) { return f; } return null; } + /** + * Returns a file object corresponding to a built-in profile + * specified by fileName. + * If there is no built-in profile with such name, then the method + * returns null. + */ + private static File getStandardProfileFile(String fileName) { + String dir = System.getProperty("java.home") + + File.separatorChar + "lib" + File.separatorChar + "cmm"; + String fullPath = dir + File.separatorChar + fileName; + File f = new File(fullPath); + if (!f.isFile()) { + //make sure file was installed in the kernel mode + try { + //kernel uses platform independent paths => + // should not use platform separator char + sun.jkernel.DownloadManager.downloadFile("lib/cmm/"+fileName); + } catch (IOException ioe) {} + } + return (f.isFile() && isChildOf(f, dir)) ? f : null; + } + + /** + * Checks whether given file resides inside give directory. + */ + private static boolean isChildOf(File f, String dirName) { + try { + File dir = new File(dirName); + String canonicalDirName = dir.getCanonicalPath(); + if (!canonicalDirName.endsWith(File.separator)) { + canonicalDirName += File.separator; + } + String canonicalFileName = f.getCanonicalPath(); + return canonicalFileName.startsWith(canonicalDirName); + } catch (IOException e) { + /* we do not expect the IOException here, because invocation + * of this function is always preceeded by isFile() call. + */ + return false; + } + } + + /** + * Checks whether built-in profile specified by fileName exists. + */ + private static boolean standardProfileExists(final String fileName) { + return AccessController.doPrivileged(new PrivilegedAction() { + public Boolean run() { + return getStandardProfileFile(fileName) != null; + } + }); + } + /* * Serialization support. From 1e716786f00d9db14dca333d1e6d47c12422cd2d Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Mon, 14 Sep 2009 11:46:16 +0400 Subject: [PATCH 014/172] 6872358: JRE AWT setBytePixels vulnerable to Heap Overflow Reviewed-by: prr, hawtin --- jdk/make/sun/awt/mapfile-vers | 1 - jdk/make/sun/awt/mapfile-vers-linux | 1 - .../sun/awt/image/ImageRepresentation.java | 32 +++----- .../share/native/sun/awt/image/awt_ImageRep.c | 78 ------------------- 4 files changed, 9 insertions(+), 103 deletions(-) diff --git a/jdk/make/sun/awt/mapfile-vers b/jdk/make/sun/awt/mapfile-vers index 06a1d5b974d..3840aa7759b 100644 --- a/jdk/make/sun/awt/mapfile-vers +++ b/jdk/make/sun/awt/mapfile-vers @@ -53,7 +53,6 @@ SUNWprivate_1.1 { Java_sun_awt_image_GifImageDecoder_initIDs; Java_sun_awt_image_GifImageDecoder_parseImage; Java_sun_awt_image_ImageRepresentation_initIDs; - Java_sun_awt_image_ImageRepresentation_setBytePixels; Java_sun_awt_image_ImageRepresentation_setDiffICM; Java_sun_awt_image_ImageRepresentation_setICMpixels; Java_sun_awt_image_ImagingLib_convolveBI; diff --git a/jdk/make/sun/awt/mapfile-vers-linux b/jdk/make/sun/awt/mapfile-vers-linux index c1f9d133adf..05a7d2b7c09 100644 --- a/jdk/make/sun/awt/mapfile-vers-linux +++ b/jdk/make/sun/awt/mapfile-vers-linux @@ -55,7 +55,6 @@ SUNWprivate_1.1 { Java_sun_awt_image_GifImageDecoder_parseImage; Java_sun_awt_image_Image_initIDs; Java_sun_awt_image_ImageRepresentation_initIDs; - Java_sun_awt_image_ImageRepresentation_setBytePixels; Java_sun_awt_image_ImageRepresentation_setDiffICM; Java_sun_awt_image_ImageRepresentation_setICMpixels; Java_sun_awt_image_ImagingLib_convolveBI; diff --git a/jdk/src/share/classes/sun/awt/image/ImageRepresentation.java b/jdk/src/share/classes/sun/awt/image/ImageRepresentation.java index ca9260b5a8c..1f034ea6e17 100644 --- a/jdk/src/share/classes/sun/awt/image/ImageRepresentation.java +++ b/jdk/src/share/classes/sun/awt/image/ImageRepresentation.java @@ -336,10 +336,6 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer public native void setICMpixels(int x, int y, int w, int h, int[] lut, byte[] pix, int off, int scansize, IntegerComponentRaster ict); - - public native void setBytePixels(int x, int y, int w, int h, byte[] pix, - int off, int scansize, - ByteComponentRaster bct, int chanOff); public native int setDiffICM(int x, int y, int w, int h, int[] lut, int transPix, int numLut, IndexColorModel icm, byte[] pix, int off, int scansize, @@ -450,27 +446,17 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer (biRaster instanceof ByteComponentRaster) && (biRaster.getNumDataElements() == 1)){ ByteComponentRaster bt = (ByteComponentRaster) biRaster; - if (w*h > 200) { - if (off == 0 && scansize == w) { - bt.putByteData(x, y, w, h, pix); - } - else { - byte[] bpix = new byte[w]; - poff = off; - for (int yoff=y; yoff < y+h; yoff++) { - System.arraycopy(pix, poff, bpix, 0, w); - bt.putByteData(x, yoff, w, 1, bpix); - poff += scansize; - } - } + if (off == 0 && scansize == w) { + bt.putByteData(x, y, w, h, pix); } else { - // Only is faster if #pixels - // Note that setBytePixels modifies the raster directly - // so we must mark it as changed afterwards - setBytePixels(x, y, w, h, pix, off, scansize, bt, - bt.getDataOffset(0)); - bt.markDirty(); + byte[] bpix = new byte[w]; + poff = off; + for (int yoff=y; yoff < y+h; yoff++) { + System.arraycopy(pix, poff, bpix, 0, w); + bt.putByteData(x, yoff, w, 1, bpix); + poff += scansize; + } } } else { diff --git a/jdk/src/share/native/sun/awt/image/awt_ImageRep.c b/jdk/src/share/native/sun/awt/image/awt_ImageRep.c index 79975ff7a35..b40eec8944c 100644 --- a/jdk/src/share/native/sun/awt/image/awt_ImageRep.c +++ b/jdk/src/share/native/sun/awt/image/awt_ImageRep.c @@ -142,84 +142,6 @@ Java_sun_awt_image_ImageRepresentation_setICMpixels(JNIEnv *env, jclass cls, } -JNIEXPORT void JNICALL -Java_sun_awt_image_ImageRepresentation_setBytePixels(JNIEnv *env, jclass cls, - jint x, jint y, jint w, - jint h, jbyteArray jpix, - jint off, jint scansize, - jobject jbct, - jint chanOffs) -{ - int sStride; - int pixelStride; - jobject jdata; - unsigned char *srcData; - unsigned char *dstData; - unsigned char *dataP; - unsigned char *pixP; - int i; - int j; - - - if (JNU_IsNull(env, jpix)) { - JNU_ThrowNullPointerException(env, "NullPointerException"); - return; - } - - sStride = (*env)->GetIntField(env, jbct, g_BCRscanstrID); - pixelStride = (*env)->GetIntField(env, jbct, g_BCRpixstrID); - jdata = (*env)->GetObjectField(env, jbct, g_BCRdataID); - - srcData = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, jpix, - NULL); - if (srcData == NULL) { - /* out of memory error already thrown */ - return; - } - - dstData = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, jdata, - NULL); - if (dstData == NULL) { - /* out of memory error already thrown */ - (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT); - return; - } - - dataP = dstData + chanOffs + y*sStride + x*pixelStride; - pixP = srcData + off; - if (pixelStride == 1) { - if (sStride == scansize && scansize == w) { - memcpy(dataP, pixP, w*h); - } - else { - for (i=0; i < h; i++) { - memcpy(dataP, pixP, w); - dataP += sStride; - pixP += scansize; - } - } - } - else { - unsigned char *ydataP = dataP; - unsigned char *ypixP = pixP; - - for (i=0; i < h; i++) { - dataP = ydataP; - pixP = ypixP; - for (j=0; j < w; j++) { - *dataP = *pixP++; - dataP += pixelStride; - } - ydataP += sStride; - ypixP += scansize; - } - } - - (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT); - (*env)->ReleasePrimitiveArrayCritical(env, jdata, dstData, JNI_ABORT); - -} - JNIEXPORT jint JNICALL Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls, jint x, jint y, jint w, From 89aa7fcef621e457418dadaaec0a577dfef9ed7d Mon Sep 17 00:00:00 2001 From: Xiaobin Lu Date: Thu, 24 Sep 2009 12:10:46 -0700 Subject: [PATCH 015/172] 6880029: JDK 1.6.0_u14p Application crashed very early Reviewed-by: never, ysr, acorn --- hotspot/src/share/vm/runtime/safepoint.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp index bbe60732c45..04a5240d734 100644 --- a/hotspot/src/share/vm/runtime/safepoint.cpp +++ b/hotspot/src/share/vm/runtime/safepoint.cpp @@ -81,6 +81,14 @@ void SafepointSynchronize::begin() { jlong safepoint_limit_time; timeout_error_printed = false; + // PrintSafepointStatisticsTimeout can be specified separately. When + // specified, PrintSafepointStatistics will be set to true in + // deferred_initialize_stat method. The initialization has to be done + // early enough to avoid any races. See bug 6880029 for details. + if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) { + deferred_initialize_stat(); + } + // Begin the process of bringing the system to a safepoint. // Java threads can be in several different states and are // stopped by different mechanisms: @@ -169,8 +177,7 @@ void SafepointSynchronize::begin() { } } - if ( (PrintSafepointStatistics || (PrintSafepointStatisticsTimeout > 0)) - && iterations == 0) { + if (PrintSafepointStatistics && iterations == 0) { begin_statistics(nof_threads, still_running); } @@ -1026,8 +1033,7 @@ void SafepointSynchronize::deferred_initialize_stat() { } void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) { - deferred_initialize_stat(); - + assert(init_done, "safepoint statistics array hasn't been initialized"); SafepointStats *spstat = &_safepoint_stats[_cur_stat_index]; VM_Operation *op = VMThread::vm_operation(); From b56db814255256e9cc73c8f91c77936062ed2e5e Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Thu, 24 Sep 2009 22:50:41 +0100 Subject: [PATCH 016/172] 6863503: SECURITY: MessageDigest.isEqual introduces timing attack vulnerabilities Reviewed-by: mullan, wetmore --- .../classes/java/security/MessageDigest.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/java/security/MessageDigest.java b/jdk/src/share/classes/java/security/MessageDigest.java index 9ff8390d92d..f08b6fd9502 100644 --- a/jdk/src/share/classes/java/security/MessageDigest.java +++ b/jdk/src/share/classes/java/security/MessageDigest.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2009 Sun Microsystems, 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 @@ -414,16 +414,17 @@ public abstract class MessageDigest extends MessageDigestSpi { * * @return true if the digests are equal, false otherwise. */ - public static boolean isEqual(byte digesta[], byte digestb[]) { - if (digesta.length != digestb.length) + public static boolean isEqual(byte[] digesta, byte[] digestb) { + if (digesta.length != digestb.length) { return false; - - for (int i = 0; i < digesta.length; i++) { - if (digesta[i] != digestb[i]) { - return false; - } } - return true; + + int result = 0; + // time-constant comparison + for (int i = 0; i < digesta.length; i++) { + result |= digesta[i] ^ digestb[i]; + } + return result == 0; } /** From 7c9b6d8d16f204d46f3b1e8f118e595aeb06c586 Mon Sep 17 00:00:00 2001 From: Antonios Printezis Date: Fri, 23 Oct 2009 14:34:27 -0400 Subject: [PATCH 017/172] 6886024: G1: assert(recent_avg_pause_time_ratio() < 1.00,"All GC?") The assert is incorrect and can fire incorrectly due to floating point inaccuracy. Reviewed-by: apetrusenko, ysr, jcoomes --- .../src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp index ecbddba4404..20e8fba5dea 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -1516,7 +1516,8 @@ void G1CollectorPolicy::record_collection_pause_end(bool abandoned) { (end_time_sec - _recent_prev_end_times_for_all_gcs_sec->oldest()) * 1000.0; update_recent_gc_times(end_time_sec, elapsed_ms); _recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms; - assert(recent_avg_pause_time_ratio() < 1.00, "All GC?"); + // using 1.01 to account for floating point inaccuracies + assert(recent_avg_pause_time_ratio() < 1.01, "All GC?"); } if (G1PolicyVerbose > 1) { From 2c2a8ae8b146e808417510f3a8ef6099a3ad4d9d Mon Sep 17 00:00:00 2001 From: Antonios Printezis Date: Wed, 30 Sep 2009 14:50:51 -0400 Subject: [PATCH 018/172] 6890137: G1: revamp reachable object dump Revamp the reachable object dump debugging facility. Reviewed-by: jmasa, apetrusenko --- .../gc_implementation/g1/concurrentMark.cpp | 201 +++++++++--------- .../gc_implementation/g1/concurrentMark.hpp | 9 +- .../gc_implementation/g1/g1CollectedHeap.cpp | 5 +- .../vm/gc_implementation/g1/g1_globals.hpp | 10 +- 4 files changed, 115 insertions(+), 110 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 9e702d63b1a..af93ae7d231 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -667,39 +667,6 @@ ConcurrentMark::~ConcurrentMark() { // Called at the first checkpoint. // -#define PRINT_REACHABLE_AT_INITIAL_MARK 0 -#if PRINT_REACHABLE_AT_INITIAL_MARK -static FILE* reachable_file = NULL; - -class PrintReachableClosure: public OopsInGenClosure { - CMBitMap* _bm; - int _level; -public: - PrintReachableClosure(CMBitMap* bm) : - _bm(bm), _level(0) { - guarantee(reachable_file != NULL, "pre-condition"); - } - void do_oop(oop* p) { - oop obj = *p; - HeapWord* obj_addr = (HeapWord*)obj; - if (obj == NULL) return; - fprintf(reachable_file, "%d: "PTR_FORMAT" -> "PTR_FORMAT" (%d)\n", - _level, p, (void*) obj, _bm->isMarked(obj_addr)); - if (!_bm->isMarked(obj_addr)) { - _bm->mark(obj_addr); - _level++; - obj->oop_iterate(this); - _level--; - } - } -}; -#endif // PRINT_REACHABLE_AT_INITIAL_MARK - -#define SEND_HEAP_DUMP_TO_FILE 0 -#if SEND_HEAP_DUMP_TO_FILE -static FILE* heap_dump_file = NULL; -#endif // SEND_HEAP_DUMP_TO_FILE - void ConcurrentMark::clearNextBitmap() { guarantee(!G1CollectedHeap::heap()->mark_in_progress(), "Precondition."); @@ -737,32 +704,9 @@ void ConcurrentMark::checkpointRootsInitialPre() { _has_aborted = false; - // Find all the reachable objects... -#if PRINT_REACHABLE_AT_INITIAL_MARK - guarantee(reachable_file == NULL, "Protocol"); - char fn_buf[100]; - sprintf(fn_buf, "/tmp/reachable.txt.%d", os::current_process_id()); - reachable_file = fopen(fn_buf, "w"); - // clear the mark bitmap (no grey objects to start with) - _nextMarkBitMap->clearAll(); - PrintReachableClosure prcl(_nextMarkBitMap); - g1h->process_strong_roots(true, // activate StrongRootsScope - false, // fake perm gen collection - SharedHeap::SO_AllClasses, - &prcl, // Regular roots - NULL, // do not visit active blobs - &prcl // Perm Gen Roots - ); - // The root iteration above "consumed" dirty cards in the perm gen. - // Therefore, as a shortcut, we dirty all such cards. - g1h->rem_set()->invalidate(g1h->perm_gen()->used_region(), false); - fclose(reachable_file); - reachable_file = NULL; - // clear the mark bitmap again. - _nextMarkBitMap->clearAll(); - COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); - COMPILER2_PRESENT(DerivedPointerTable::clear()); -#endif // PRINT_REACHABLE_AT_INITIAL_MARK + if (G1PrintReachableAtInitialMark) { + print_reachable(true, "before"); + } // Initialise marking structures. This has to be done in a STW phase. reset(); @@ -1965,15 +1909,21 @@ void ConcurrentMark::checkpointRootsFinalWork() { #endif } +#ifndef PRODUCT + class ReachablePrinterOopClosure: public OopClosure { private: G1CollectedHeap* _g1h; CMBitMapRO* _bitmap; outputStream* _out; + bool _use_prev_marking; public: - ReachablePrinterOopClosure(CMBitMapRO* bitmap, outputStream* out) : - _bitmap(bitmap), _g1h(G1CollectedHeap::heap()), _out(out) { } + ReachablePrinterOopClosure(CMBitMapRO* bitmap, + outputStream* out, + bool use_prev_marking) : + _g1h(G1CollectedHeap::heap()), + _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } void do_oop(narrowOop* p) { do_oop_work(p); } void do_oop( oop* p) { do_oop_work(p); } @@ -1988,14 +1938,23 @@ public: else { HeapRegion* hr = _g1h->heap_region_containing(obj); guarantee(hr != NULL, "invariant"); - if (hr->obj_allocated_since_prev_marking(obj)) { + bool over_tams = false; + if (_use_prev_marking) { + over_tams = hr->obj_allocated_since_prev_marking(obj); + } else { + over_tams = hr->obj_allocated_since_next_marking(obj); + } + + if (over_tams) { str = "over TAMS"; - if (_bitmap->isMarked((HeapWord*) obj)) + if (_bitmap->isMarked((HeapWord*) obj)) { str2 = " AND MARKED"; - } else if (_bitmap->isMarked((HeapWord*) obj)) + } + } else if (_bitmap->isMarked((HeapWord*) obj)) { str = "marked"; - else + } else { str = "#### NOT MARKED ####"; + } } _out->print_cr(" "PTR_FORMAT" contains "PTR_FORMAT" %s%s", @@ -2005,16 +1964,19 @@ public: class ReachablePrinterClosure: public BitMapClosure { private: - CMBitMapRO* _bitmap; + CMBitMapRO* _bitmap; outputStream* _out; + bool _use_prev_marking; public: - ReachablePrinterClosure(CMBitMapRO* bitmap, outputStream* out) : - _bitmap(bitmap), _out(out) { } + ReachablePrinterClosure(CMBitMapRO* bitmap, + outputStream* out, + bool use_prev_marking) : + _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } bool do_bit(size_t offset) { HeapWord* addr = _bitmap->offsetToHeapWord(offset); - ReachablePrinterOopClosure oopCl(_bitmap, _out); + ReachablePrinterOopClosure oopCl(_bitmap, _out, _use_prev_marking); _out->print_cr(" obj "PTR_FORMAT", offset %10d (marked)", addr, offset); oop(addr)->oop_iterate(&oopCl); @@ -2026,76 +1988,111 @@ public: class ObjInRegionReachablePrinterClosure : public ObjectClosure { private: - CMBitMapRO* _bitmap; + CMBitMapRO* _bitmap; outputStream* _out; + bool _use_prev_marking; public: + ObjInRegionReachablePrinterClosure(CMBitMapRO* bitmap, + outputStream* out, + bool use_prev_marking) : + _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } + void do_object(oop o) { - ReachablePrinterOopClosure oopCl(_bitmap, _out); + ReachablePrinterOopClosure oopCl(_bitmap, _out, _use_prev_marking); _out->print_cr(" obj "PTR_FORMAT" (over TAMS)", (void*) o); o->oop_iterate(&oopCl); _out->print_cr(""); } - - ObjInRegionReachablePrinterClosure(CMBitMapRO* bitmap, outputStream* out) : - _bitmap(bitmap), _out(out) { } }; class RegionReachablePrinterClosure : public HeapRegionClosure { private: - CMBitMapRO* _bitmap; + CMBitMapRO* _bitmap; outputStream* _out; + bool _use_prev_marking; public: bool doHeapRegion(HeapRegion* hr) { HeapWord* b = hr->bottom(); HeapWord* e = hr->end(); HeapWord* t = hr->top(); - HeapWord* p = hr->prev_top_at_mark_start(); + HeapWord* p = NULL; + if (_use_prev_marking) { + p = hr->prev_top_at_mark_start(); + } else { + p = hr->next_top_at_mark_start(); + } _out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" " - "PTAMS: "PTR_FORMAT, b, e, t, p); + "TAMS: "PTR_FORMAT, b, e, t, p); _out->print_cr(""); - ObjInRegionReachablePrinterClosure ocl(_bitmap, _out); + ObjInRegionReachablePrinterClosure ocl(_bitmap, _out, _use_prev_marking); hr->object_iterate_mem_careful(MemRegion(p, t), &ocl); return false; } - RegionReachablePrinterClosure(CMBitMapRO* bitmap, - outputStream* out) : - _bitmap(bitmap), _out(out) { } + RegionReachablePrinterClosure(CMBitMapRO* bitmap, + outputStream* out, + bool use_prev_marking) : + _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } }; -void ConcurrentMark::print_prev_bitmap_reachable() { - outputStream* out = gclog_or_tty; +void ConcurrentMark::print_reachable(bool use_prev_marking, const char* str) { + gclog_or_tty->print_cr("== Doing reachable object dump... "); -#if SEND_HEAP_DUMP_TO_FILE - guarantee(heap_dump_file == NULL, "Protocol"); - char fn_buf[100]; - sprintf(fn_buf, "/tmp/dump.txt.%d", os::current_process_id()); - heap_dump_file = fopen(fn_buf, "w"); - fileStream fstream(heap_dump_file); - out = &fstream; -#endif // SEND_HEAP_DUMP_TO_FILE + if (G1PrintReachableBaseFile == NULL) { + gclog_or_tty->print_cr(" #### error: no base file defined"); + return; + } - RegionReachablePrinterClosure rcl(_prevMarkBitMap, out); - out->print_cr("--- ITERATING OVER REGIONS WITH PTAMS < TOP"); + if (strlen(G1PrintReachableBaseFile) + 1 + strlen(str) > + (JVM_MAXPATHLEN - 1)) { + gclog_or_tty->print_cr(" #### error: file name too long"); + return; + } + + char file_name[JVM_MAXPATHLEN]; + sprintf(file_name, "%s.%s", G1PrintReachableBaseFile, str); + gclog_or_tty->print_cr(" dumping to file %s", file_name); + + fileStream fout(file_name); + if (!fout.is_open()) { + gclog_or_tty->print_cr(" #### error: could not open file"); + return; + } + + outputStream* out = &fout; + + CMBitMapRO* bitmap = NULL; + if (use_prev_marking) { + bitmap = _prevMarkBitMap; + } else { + bitmap = _nextMarkBitMap; + } + + out->print_cr("-- USING %s", (use_prev_marking) ? "PTAMS" : "NTAMS"); + out->cr(); + + RegionReachablePrinterClosure rcl(bitmap, out, use_prev_marking); + out->print_cr("--- ITERATING OVER REGIONS WITH TAMS < TOP"); + out->cr(); _g1h->heap_region_iterate(&rcl); - out->print_cr(""); + out->cr(); - ReachablePrinterClosure cl(_prevMarkBitMap, out); - out->print_cr("--- REACHABLE OBJECTS ON THE BITMAP"); - _prevMarkBitMap->iterate(&cl); - out->print_cr(""); + ReachablePrinterClosure cl(bitmap, out, use_prev_marking); + out->print_cr("--- ITERATING OVER MARKED OBJECTS ON THE BITMAP"); + out->cr(); + bitmap->iterate(&cl); + out->cr(); -#if SEND_HEAP_DUMP_TO_FILE - fclose(heap_dump_file); - heap_dump_file = NULL; -#endif // SEND_HEAP_DUMP_TO_FILE + gclog_or_tty->print_cr(" done"); } +#endif // PRODUCT + // This note is for drainAllSATBBuffers and the code in between. // In the future we could reuse a task to do this work during an // evacuation pause (since now tasks are not active and can be claimed diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp index 8cf0207dbb3..f6902c86330 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp @@ -612,10 +612,11 @@ public: // we do nothing. void markAndGrayObjectIfNecessary(oop p); - // This iterates over the bitmap of the previous marking and prints - // out all objects that are marked on the bitmap and indicates - // whether what they point to is also marked or not. - void print_prev_bitmap_reachable(); + // This iterates over the marking bitmap (either prev or next) and + // prints out all objects that are marked on the bitmap and indicates + // whether what they point to is also marked or not. It also iterates + // the objects over TAMS (either prev or next). + void print_reachable(bool use_prev_marking, const char* str); // Clear the next marking bitmap (will be called concurrently). void clearNextBitmap(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 29c5c075d86..b45830037b5 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2371,8 +2371,9 @@ void G1CollectedHeap::verify(bool allow_dirty, gclog_or_tty->print_cr("Heap:"); print_on(gclog_or_tty, true /* extended */); gclog_or_tty->print_cr(""); - if (VerifyDuringGC && G1VerifyConcMarkPrintReachable) { - concurrent_mark()->print_prev_bitmap_reachable(); + if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) { + concurrent_mark()->print_reachable(use_prev_marking, + "failed-verification"); } gclog_or_tty->flush(); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp index b56a0281313..c941c8755d6 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp @@ -55,8 +55,14 @@ develop(intx, G1MarkingVerboseLevel, 0, \ "Level (0-4) of verboseness of the marking code") \ \ - develop(bool, G1VerifyConcMarkPrintReachable, false, \ - "If conc mark verification fails, print reachable objects") \ + develop(bool, G1PrintReachableAtInitialMark, false, \ + "Reachable object dump at the initial mark pause") \ + \ + develop(bool, G1VerifyDuringGCPrintReachable, false, \ + "If conc mark verification fails, dump reachable objects") \ + \ + develop(ccstr, G1PrintReachableBaseFile, NULL, \ + "The base file name for the reachable object dumps") \ \ develop(bool, G1TraceMarkStackOverflow, false, \ "If true, extra debugging code for CM restart for ovflw.") \ From 3fa31de79197d70e8819d31161331c4952eabae5 Mon Sep 17 00:00:00 2001 From: Igor Nekrestyanov Date: Fri, 2 Oct 2009 10:15:12 -0700 Subject: [PATCH 019/172] 6887292: memory leak in freetypeScaler.c Reviewed-by: bae, prr --- jdk/src/share/native/sun/font/freetypeScaler.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/jdk/src/share/native/sun/font/freetypeScaler.c b/jdk/src/share/native/sun/font/freetypeScaler.c index 4028d4d97c4..93baaea47cd 100644 --- a/jdk/src/share/native/sun/font/freetypeScaler.c +++ b/jdk/src/share/native/sun/font/freetypeScaler.c @@ -102,9 +102,21 @@ Java_sun_font_FreetypeFontScaler_initIDs( } static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) { + void *stream; + if (scalerInfo == NULL) return; + //apparently Done_Face will only close the stream + // but will not relase the memory of stream structure. + // We need to free it explicitly to avoid leak. + //Direct access to the stream field might be not ideal solution as + // it is considred to be "private". + //Alternatively we could have stored pointer to the structure + // in the scalerInfo but this will increase size of the structure + // for no good reason + stream = scalerInfo->face->stream; + FT_Done_Face(scalerInfo->face); FT_Done_FreeType(scalerInfo->library); @@ -116,6 +128,10 @@ static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) { free(scalerInfo->fontData); } + if (stream != NULL) { + free(stream); + } + free(scalerInfo); } From e379759e1b29ee824f85e334a1c59d3b0b273b13 Mon Sep 17 00:00:00 2001 From: John Coomes Date: Mon, 5 Oct 2009 05:51:22 -0700 Subject: [PATCH 020/172] 6887948: test/gc/6845368/bigobj.java fails due to timeout Reviewed-by: iveresov --- hotspot/test/gc/6845368/bigobj.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/test/gc/6845368/bigobj.java b/hotspot/test/gc/6845368/bigobj.java index 087bdc9236b..5185326bb4a 100644 --- a/hotspot/test/gc/6845368/bigobj.java +++ b/hotspot/test/gc/6845368/bigobj.java @@ -3,7 +3,7 @@ @bug 6845368 @summary ensure gc updates references > 64K bytes from the start of the obj @author John Coomes - @run main/othervm -Xmx64m bigobj + @run main/othervm/timeout=720 -Xmx64m bigobj */ // Allocate an object with a block of reference fields that starts more From 99a529bb86bd62cfbff6ca937e0490a0179d3746 Mon Sep 17 00:00:00 2001 From: Antonios Printezis Date: Fri, 2 Oct 2009 16:12:07 -0400 Subject: [PATCH 021/172] 6885041: G1: inconsistent thread dump When G1 is enabled, thread dumps are inconsistent as the info for some of the G1 threads is not formatted properly. Reviewed-by: ysr, johnc --- .../g1/concurrentG1Refine.cpp | 8 ++++++ .../g1/concurrentG1Refine.hpp | 2 ++ .../g1/concurrentG1RefineThread.cpp | 12 ++++++--- .../g1/concurrentG1RefineThread.hpp | 3 ++- .../gc_implementation/g1/concurrentMark.cpp | 6 ++++- .../gc_implementation/g1/concurrentMark.hpp | 2 ++ .../g1/concurrentMarkThread.cpp | 12 ++++++--- .../g1/concurrentMarkThread.hpp | 3 ++- .../g1/concurrentZFThread.cpp | 12 ++++++--- .../g1/concurrentZFThread.hpp | 3 ++- .../gc_implementation/g1/g1CollectedHeap.cpp | 25 ++++++------------- 11 files changed, 55 insertions(+), 33 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp index 8ec60012c04..34939de57c7 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp @@ -377,3 +377,11 @@ void ConcurrentG1Refine::clear_and_record_card_counts() { _g1h->g1_policy()->record_cc_clear_time(elapsed * 1000.0); #endif } + +void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const { + for (int i = 0; i < _n_threads; ++i) { + _threads[i]->print_on(st); + st->cr(); + } +} + diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp index a6ee5484a37..5cef3058ca4 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp @@ -179,4 +179,6 @@ class ConcurrentG1Refine: public CHeapObj { void clear_and_record_card_counts(); static size_t thread_num(); + + void print_worker_threads_on(outputStream* st) const; }; diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp index 1954c949f61..aaf2544fe9b 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp @@ -204,8 +204,12 @@ void ConcurrentG1RefineThread::stop() { if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-stop"); } -void ConcurrentG1RefineThread::print() { - gclog_or_tty->print("\"Concurrent G1 Refinement Thread\" "); - Thread::print(); - gclog_or_tty->cr(); +void ConcurrentG1RefineThread::print() const { + print_on(tty); +} + +void ConcurrentG1RefineThread::print_on(outputStream* st) const { + st->print("\"G1 Concurrent Refinement Thread#%d\" ", _worker_id); + Thread::print_on(st); + st->cr(); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp index 05a3243a115..167fc176ef7 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp @@ -77,7 +77,8 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread { int worker_id_offset, int worker_id); // Printing - void print(); + void print() const; + void print_on(outputStream* st) const; // Total virtual time so far. double vtime_accum() { return _vtime_accum; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 08d5e76e788..59ba0f59c84 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -543,7 +543,7 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs, #endif guarantee( parallel_marking_threads() > 0, "peace of mind" ); - _parallel_workers = new WorkGang("Parallel Marking Threads", + _parallel_workers = new WorkGang("G1 Parallel Marking Threads", (int) parallel_marking_threads(), false, true); if (_parallel_workers == NULL) vm_exit_during_initialization("Failed necessary allocation."); @@ -2637,6 +2637,10 @@ void ConcurrentMark::print_summary_info() { cmThread()->vtime_count_accum()); } +void ConcurrentMark::print_worker_threads_on(outputStream* st) const { + _parallel_workers->print_worker_threads_on(st); +} + // Closures // XXX: there seems to be a lot of code duplication here; // should refactor and consolidate the shared code. diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp index 010108f9300..eae6ef94bfd 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp @@ -723,6 +723,8 @@ public: void print_summary_info(); + void print_worker_threads_on(outputStream* st) const; + // The following indicate whether a given verbose level has been // set. Notice that anything above stats is conditional to // _MARKING_VERBOSE_ having been set to 1 diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp index 445a342c862..b1a8b2a7b46 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp @@ -286,10 +286,14 @@ void ConcurrentMarkThread::stop() { } } -void ConcurrentMarkThread::print() { - gclog_or_tty->print("\"Concurrent Mark GC Thread\" "); - Thread::print(); - gclog_or_tty->cr(); +void ConcurrentMarkThread::print() const { + print_on(tty); +} + +void ConcurrentMarkThread::print_on(outputStream* st) const { + st->print("\"G1 Main Concurrent Mark GC Thread\" "); + Thread::print_on(st); + st->cr(); } void ConcurrentMarkThread::sleepBeforeNextCycle() { diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp index e439bdb44d1..77f8f35753f 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp @@ -57,7 +57,8 @@ class ConcurrentMarkThread: public ConcurrentGCThread { static SurrogateLockerThread* slt() { return _slt; } // Printing - void print(); + void print_on(outputStream* st) const; + void print() const; // Total virtual time so far. double vtime_accum(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.cpp index 436b01613f9..f41355cd79b 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.cpp @@ -157,10 +157,14 @@ void ConcurrentZFThread::stop() { } } -void ConcurrentZFThread::print() { - gclog_or_tty->print("\"Concurrent ZF Thread\" "); - Thread::print(); - gclog_or_tty->cr(); +void ConcurrentZFThread::print() const { + print_on(tty); +} + +void ConcurrentZFThread::print_on(outputStream* st) const { + st->print("\"G1 Concurrent Zero-Fill Thread\" "); + Thread::print_on(st); + st->cr(); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.hpp index d7f4cfa0c5f..75774942e85 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.hpp @@ -61,7 +61,8 @@ class ConcurrentZFThread: public ConcurrentGCThread { virtual void run(); // Printing - void print(); + void print_on(outputStream* st) const; + void print() const; // Waits until "r" has been zero-filled. Requires caller to hold the // ZF_mon. diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 62e987f2b1c..e9ed79da718 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2383,27 +2383,18 @@ void G1CollectedHeap::print_on_extended(outputStream* st) const { _hrs->iterate(&blk); } -class PrintOnThreadsClosure : public ThreadClosure { - outputStream* _st; -public: - PrintOnThreadsClosure(outputStream* st) : _st(st) { } - virtual void do_thread(Thread *t) { - t->print_on(_st); - } -}; - void G1CollectedHeap::print_gc_threads_on(outputStream* st) const { if (ParallelGCThreads > 0) { - workers()->print_worker_threads(); + workers()->print_worker_threads_on(st); } - st->print("\"G1 concurrent mark GC Thread\" "); - _cmThread->print(); + + _cmThread->print_on(st); st->cr(); - st->print("\"G1 concurrent refinement GC Threads\" "); - PrintOnThreadsClosure p(st); - _cg1r->threads_do(&p); - st->cr(); - st->print("\"G1 zero-fill GC Thread\" "); + + _cm->print_worker_threads_on(st); + + _cg1r->print_worker_threads_on(st); + _czft->print_on(st); st->cr(); } From 2684c3a4312b537d225cb8e1a100e9fc13f7788f Mon Sep 17 00:00:00 2001 From: Antonios Printezis Date: Fri, 2 Oct 2009 16:20:42 -0400 Subject: [PATCH 022/172] 6882730: G1: parallel heap verification messes up region dump It tidies up the G1 heap verification a bit. In particular, when the verification is done in parallel and there is a failure, this is propagated to the top level and the heap is dumped at the end, not by every thread that encounters a failure. Reviewed-by: johnc, jmasa --- .../gc_implementation/g1/g1CollectedHeap.cpp | 71 +++++++++++++--- .../vm/gc_implementation/g1/heapRegion.cpp | 80 +++++++++++++------ .../vm/gc_implementation/g1/heapRegion.hpp | 2 +- 3 files changed, 116 insertions(+), 37 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index e9ed79da718..29c5c075d86 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2210,40 +2210,58 @@ private: bool _allow_dirty; bool _par; bool _use_prev_marking; + bool _failures; public: // use_prev_marking == true -> use "prev" marking information, // use_prev_marking == false -> use "next" marking information VerifyRegionClosure(bool allow_dirty, bool par, bool use_prev_marking) : _allow_dirty(allow_dirty), _par(par), - _use_prev_marking(use_prev_marking) {} + _use_prev_marking(use_prev_marking), + _failures(false) {} + + bool failures() { + return _failures; + } bool doHeapRegion(HeapRegion* r) { guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue, "Should be unclaimed at verify points."); if (!r->continuesHumongous()) { - VerifyObjsInRegionClosure not_dead_yet_cl(r, _use_prev_marking); - r->verify(_allow_dirty, _use_prev_marking); - r->object_iterate(¬_dead_yet_cl); - guarantee(r->max_live_bytes() >= not_dead_yet_cl.live_bytes(), - "More live objects than counted in last complete marking."); + bool failures = false; + r->verify(_allow_dirty, _use_prev_marking, &failures); + if (failures) { + _failures = true; + } else { + VerifyObjsInRegionClosure not_dead_yet_cl(r, _use_prev_marking); + r->object_iterate(¬_dead_yet_cl); + if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) { + gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] " + "max_live_bytes "SIZE_FORMAT" " + "< calculated "SIZE_FORMAT, + r->bottom(), r->end(), + r->max_live_bytes(), + not_dead_yet_cl.live_bytes()); + _failures = true; + } + } } - return false; + return false; // stop the region iteration if we hit a failure } }; class VerifyRootsClosure: public OopsInGenClosure { private: G1CollectedHeap* _g1h; - bool _failures; bool _use_prev_marking; + bool _failures; public: // use_prev_marking == true -> use "prev" marking information, // use_prev_marking == false -> use "next" marking information VerifyRootsClosure(bool use_prev_marking) : _g1h(G1CollectedHeap::heap()), - _failures(false), - _use_prev_marking(use_prev_marking) { } + _use_prev_marking(use_prev_marking), + _failures(false) { } bool failures() { return _failures; } @@ -2253,7 +2271,7 @@ public: oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); if (_g1h->is_obj_dead_cond(obj, _use_prev_marking)) { gclog_or_tty->print_cr("Root location "PTR_FORMAT" " - "points to dead obj "PTR_FORMAT, p, (void*) obj); + "points to dead obj "PTR_FORMAT, p, (void*) obj); obj->print_on(gclog_or_tty); _failures = true; } @@ -2271,6 +2289,7 @@ private: G1CollectedHeap* _g1h; bool _allow_dirty; bool _use_prev_marking; + bool _failures; public: // use_prev_marking == true -> use "prev" marking information, @@ -2280,13 +2299,21 @@ public: AbstractGangTask("Parallel verify task"), _g1h(g1h), _allow_dirty(allow_dirty), - _use_prev_marking(use_prev_marking) { } + _use_prev_marking(use_prev_marking), + _failures(false) { } + + bool failures() { + return _failures; + } void work(int worker_i) { HandleMark hm; VerifyRegionClosure blk(_allow_dirty, true, _use_prev_marking); _g1h->heap_region_par_iterate_chunked(&blk, worker_i, HeapRegion::ParVerifyClaimValue); + if (blk.failures()) { + _failures = true; + } } }; @@ -2307,6 +2334,7 @@ void G1CollectedHeap::verify(bool allow_dirty, &rootsCl, &blobsCl, &rootsCl); + bool failures = rootsCl.failures(); rem_set()->invalidate(perm_gen()->used_region(), false); if (!silent) { gclog_or_tty->print("heapRegions "); } if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { @@ -2318,6 +2346,9 @@ void G1CollectedHeap::verify(bool allow_dirty, set_par_threads(n_workers); workers()->run_task(&task); set_par_threads(0); + if (task.failures()) { + failures = true; + } assert(check_heap_region_claim_values(HeapRegion::ParVerifyClaimValue), "sanity check"); @@ -2329,10 +2360,23 @@ void G1CollectedHeap::verify(bool allow_dirty, } else { VerifyRegionClosure blk(allow_dirty, false, use_prev_marking); _hrs->iterate(&blk); + if (blk.failures()) { + failures = true; + } } if (!silent) gclog_or_tty->print("remset "); rem_set()->verify(); - guarantee(!rootsCl.failures(), "should not have had failures"); + + if (failures) { + gclog_or_tty->print_cr("Heap:"); + print_on(gclog_or_tty, true /* extended */); + gclog_or_tty->print_cr(""); + if (VerifyDuringGC && G1VerifyConcMarkPrintReachable) { + concurrent_mark()->print_prev_bitmap_reachable(); + } + gclog_or_tty->flush(); + } + guarantee(!failures, "there should not have been any failures"); } else { if (!silent) gclog_or_tty->print("(SKIPPING roots, heapRegions, remset) "); } @@ -2374,6 +2418,7 @@ void G1CollectedHeap::print_on(outputStream* st, bool extended) const { st->cr(); perm()->as_gen()->print_on(st); if (extended) { + st->cr(); print_on_extended(st); } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp index 6cbdf87583b..8afaee40a85 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -722,12 +722,13 @@ void HeapRegion::print_on(outputStream* st) const { st->print(" F"); else st->print(" "); - st->print(" %d", _gc_time_stamp); + st->print(" %5d", _gc_time_stamp); G1OffsetTableContigSpace::print_on(st); } void HeapRegion::verify(bool allow_dirty) const { - verify(allow_dirty, /* use_prev_marking */ true); + bool dummy = false; + verify(allow_dirty, /* use_prev_marking */ true, /* failures */ &dummy); } #define OBJ_SAMPLE_INTERVAL 0 @@ -736,8 +737,11 @@ void HeapRegion::verify(bool allow_dirty) const { // This really ought to be commoned up into OffsetTableContigSpace somehow. // We would need a mechanism to make that code skip dead objects. -void HeapRegion::verify(bool allow_dirty, bool use_prev_marking) const { +void HeapRegion::verify(bool allow_dirty, + bool use_prev_marking, + bool* failures) const { G1CollectedHeap* g1 = G1CollectedHeap::heap(); + *failures = false; HeapWord* p = bottom(); HeapWord* prev_p = NULL; int objs = 0; @@ -746,8 +750,14 @@ void HeapRegion::verify(bool allow_dirty, bool use_prev_marking) const { while (p < top()) { size_t size = oop(p)->size(); if (blocks == BLOCK_SAMPLE_INTERVAL) { - guarantee(p == block_start_const(p + (size/2)), - "check offset computation"); + HeapWord* res = block_start_const(p + (size/2)); + if (p != res) { + gclog_or_tty->print_cr("offset computation 1 for "PTR_FORMAT" and " + SIZE_FORMAT" returned "PTR_FORMAT, + p, size, res); + *failures = true; + return; + } blocks = 0; } else { blocks++; @@ -755,11 +765,34 @@ void HeapRegion::verify(bool allow_dirty, bool use_prev_marking) const { if (objs == OBJ_SAMPLE_INTERVAL) { oop obj = oop(p); if (!g1->is_obj_dead_cond(obj, this, use_prev_marking)) { - obj->verify(); - vl_cl.set_containing_obj(obj); - obj->oop_iterate(&vl_cl); - if (G1MaxVerifyFailures >= 0 - && vl_cl.n_failures() >= G1MaxVerifyFailures) break; + if (obj->is_oop()) { + klassOop klass = obj->klass(); + if (!klass->is_perm()) { + gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " + "not in perm", klass, obj); + *failures = true; + return; + } else if (!klass->is_klass()) { + gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " + "not a klass", klass, obj); + *failures = true; + return; + } else { + vl_cl.set_containing_obj(obj); + obj->oop_iterate(&vl_cl); + if (vl_cl.failures()) { + *failures = true; + } + if (G1MaxVerifyFailures >= 0 && + vl_cl.n_failures() >= G1MaxVerifyFailures) { + return; + } + } + } else { + gclog_or_tty->print_cr(PTR_FORMAT" no an oop", obj); + *failures = true; + return; + } } objs = 0; } else { @@ -771,21 +804,22 @@ void HeapRegion::verify(bool allow_dirty, bool use_prev_marking) const { HeapWord* rend = end(); HeapWord* rtop = top(); if (rtop < rend) { - guarantee(block_start_const(rtop + (rend - rtop) / 2) == rtop, - "check offset computation"); + HeapWord* res = block_start_const(rtop + (rend - rtop) / 2); + if (res != rtop) { + gclog_or_tty->print_cr("offset computation 2 for "PTR_FORMAT" and " + PTR_FORMAT" returned "PTR_FORMAT, + rtop, rend, res); + *failures = true; + return; + } } - if (vl_cl.failures()) { - gclog_or_tty->print_cr("Heap:"); - G1CollectedHeap::heap()->print_on(gclog_or_tty, true /* extended */); - gclog_or_tty->print_cr(""); + + if (p != top()) { + gclog_or_tty->print_cr("end of last object "PTR_FORMAT" " + "does not match top "PTR_FORMAT, p, top()); + *failures = true; + return; } - if (VerifyDuringGC && - G1VerifyConcMarkPrintReachable && - vl_cl.failures()) { - g1->concurrent_mark()->print_prev_bitmap_reachable(); - } - guarantee(!vl_cl.failures(), "region verification failed"); - guarantee(p == top(), "end of last object must match end of space"); } // G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp index 9a96a84da55..9b889522062 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp @@ -798,7 +798,7 @@ class HeapRegion: public G1OffsetTableContigSpace { // use_prev_marking == true. Currently, there is only one case where // this is called with use_prev_marking == false, which is to verify // the "next" marking information at the end of remark. - void verify(bool allow_dirty, bool use_prev_marking) const; + void verify(bool allow_dirty, bool use_prev_marking, bool *failures) const; // Override; it uses the "prev" marking information virtual void verify(bool allow_dirty) const; From 31de6adee95f165826ac92f26609f428dcf6268a Mon Sep 17 00:00:00 2001 From: Antonios Printezis Date: Mon, 5 Oct 2009 12:05:48 -0400 Subject: [PATCH 023/172] 6847956: G1: crash in oopDesc*G1ParCopyHelper::copy_to_survivor_space(oopDesc*) When we copy objects to survivors during marking, we incorrectly set NTAMS to bottom, which causes marking to miss visiting some of those objects. Reviewed-by: apetrusenko, iveresov --- hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp index 9b889522062..fd88a3798b4 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp @@ -569,13 +569,8 @@ class HeapRegion: public G1OffsetTableContigSpace { // ever evacuated into this region. If we evacuate, allocate, and // then evacuate we are in deep doodoo. void note_end_of_copying() { - assert(top() >= _next_top_at_mark_start, - "Increase only"); - // Survivor regions will be scanned on the start of concurrent - // marking. - if (!is_survivor()) { - _next_top_at_mark_start = top(); - } + assert(top() >= _next_top_at_mark_start, "Increase only"); + _next_top_at_mark_start = top(); } // Returns "false" iff no object in the region was allocated when the From a64ba16c4fda0e7e0f05494d4c89e1f2e9659d52 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Mon, 5 Oct 2009 23:12:22 +0200 Subject: [PATCH 024/172] 6887494: NPE in pisces Renderer Only recreate crossings array, if there actually exists one before. Reviewed-by: flar, tdv --- .../classes/sun/java2d/pisces/Renderer.java | 6 +- .../sun/java2d/pisces/Renderer/TestNPE.java | 59 +++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 jdk/test/sun/java2d/pisces/Renderer/TestNPE.java diff --git a/jdk/src/share/classes/sun/java2d/pisces/Renderer.java b/jdk/src/share/classes/sun/java2d/pisces/Renderer.java index 3ada6c73600..2aba4112161 100644 --- a/jdk/src/share/classes/sun/java2d/pisces/Renderer.java +++ b/jdk/src/share/classes/sun/java2d/pisces/Renderer.java @@ -775,10 +775,12 @@ public class Renderer extends LineSink { // Free sorting arrays if larger than maximum size private void crossingListFinished() { - if (crossings.length > DEFAULT_CROSSINGS_SIZE) { + if (crossings != null && crossings.length > DEFAULT_CROSSINGS_SIZE) { crossings = new int[DEFAULT_CROSSINGS_SIZE]; } - if (crossingIndices.length > DEFAULT_INDICES_SIZE) { + if (crossingIndices != null && + crossingIndices.length > DEFAULT_INDICES_SIZE) + { crossingIndices = new int[DEFAULT_INDICES_SIZE]; } } diff --git a/jdk/test/sun/java2d/pisces/Renderer/TestNPE.java b/jdk/test/sun/java2d/pisces/Renderer/TestNPE.java new file mode 100644 index 00000000000..440860c9272 --- /dev/null +++ b/jdk/test/sun/java2d/pisces/Renderer/TestNPE.java @@ -0,0 +1,59 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6887494 + * + * @summary Verifies that no NullPointerException is thrown in Pisces Renderer + * under certain circumstances. + * + * @run main TestNPE + */ + +import java.awt.*; +import java.awt.geom.*; +import java.awt.image.BufferedImage; + +public class TestNPE { + + private static void paint(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setClip(0, 0, 0, 0); + g2d.setTransform( + new AffineTransform(4.0f, 0.0f, 0.0f, 4.0f, -1248.0f, -744.0f)); + g2d.draw(new Line2D.Float(131.21428571428572f, 33.0f, + 131.21428571428572f, 201.0f)); + } + + public static void main(String[] args) { + BufferedImage im = new BufferedImage(100, 100, + BufferedImage.TYPE_INT_ARGB); + + // Trigger exception in main thread. + Graphics g = im.getGraphics(); + paint(g); + } +} From e4541dcd0862a0e1c1418e32321b7309e0f2caa7 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Tue, 6 Oct 2009 02:11:49 -0700 Subject: [PATCH 025/172] 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845 For signatures with a large number of arguments the offset for the float store becomes too big and does not fit in 13-bit. Reviewed-by: kvn, never --- hotspot/src/cpu/sparc/vm/assembler_sparc.cpp | 6 +- hotspot/src/cpu/sparc/vm/assembler_sparc.hpp | 17 ++-- .../cpu/sparc/vm/assembler_sparc.inline.hpp | 11 +++ .../src/cpu/sparc/vm/sharedRuntime_sparc.cpp | 88 +++++++++---------- .../test/compiler/6879902/Test6879902.java | 49 +++++++++++ 5 files changed, 116 insertions(+), 55 deletions(-) create mode 100644 hotspot/test/compiler/6879902/Test6879902.java diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp index 5899e4e9ae9..e4799550fd8 100644 --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp @@ -2631,13 +2631,13 @@ void MacroAssembler::regcon_inc_ptr( RegisterOrConstant& dest, RegisterOrConstan (src.is_register() && src.as_register() == G0)) { // do nothing } else if (dest.is_register()) { - add(dest.as_register(), ensure_rs2(src, temp), dest.as_register()); + add(dest.as_register(), ensure_simm13_or_reg(src, temp), dest.as_register()); } else if (src.is_constant()) { intptr_t res = dest.as_constant() + src.as_constant(); dest = RegisterOrConstant(res); // side effect seen by caller } else { assert(temp != noreg, "cannot handle constant += register"); - add(src.as_register(), ensure_rs2(dest, temp), temp); + add(src.as_register(), ensure_simm13_or_reg(dest, temp), temp); dest = RegisterOrConstant(temp); // side effect seen by caller } } @@ -2710,7 +2710,7 @@ void MacroAssembler::lookup_interface_method(Register recv_klass, RegisterOrConstant itable_offset = itable_index; regcon_sll_ptr(itable_offset, exact_log2(itableMethodEntry::size() * wordSize)); regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes()); - add(recv_klass, ensure_rs2(itable_offset, sethi_temp), recv_klass); + add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass); // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { // if (scan->interface() == intf) { diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp index 163c59783b1..1e184bd4584 100644 --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp @@ -1279,6 +1279,7 @@ public: // 171 + inline void ldf(FloatRegisterImpl::Width w, Register s1, RegisterOrConstant s2, FloatRegister d); inline void ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d); inline void ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec = RelocationHolder()); @@ -1535,7 +1536,8 @@ public: // pp 222 - inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2 ); + inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, RegisterOrConstant s2); + inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2); inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a); inline void stf( FloatRegisterImpl::Width w, FloatRegister d, const Address& a, int offset = 0); @@ -2049,12 +2051,13 @@ public: Register temp = noreg ); void regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp = noreg ); - RegisterOrConstant ensure_rs2(RegisterOrConstant rs2, Register sethi_temp) { - guarantee(sethi_temp != noreg, "constant offset overflow"); - if (is_simm13(rs2.constant_or_zero())) - return rs2; // register or short constant - set(rs2.as_constant(), sethi_temp); - return sethi_temp; + + RegisterOrConstant ensure_simm13_or_reg(RegisterOrConstant roc, Register Rtemp) { + guarantee(Rtemp != noreg, "constant offset overflow"); + if (is_simm13(roc.constant_or_zero())) + return roc; // register or short constant + set(roc.as_constant(), Rtemp); + return RegisterOrConstant(Rtemp); } // -------------------------------------------------- diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp index b9708ffb2b3..6ec0d8d2ed3 100644 --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp @@ -99,6 +99,11 @@ inline void Assembler::flush( Register s1, int simm13a) { emit_data( op(arith_op inline void Assembler::jmpl( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); has_delay_slot(); } +inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, RegisterOrConstant s2, FloatRegister d) { + if (s2.is_register()) ldf(w, s1, s2.as_register(), d); + else ldf(w, s1, s2.as_constant(), d); +} + inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_long( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); } @@ -224,6 +229,11 @@ inline void Assembler::sethi( int imm22a, Register d, RelocationHolder const& rs // pp 222 +inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, RegisterOrConstant s2) { + if (s2.is_register()) stf(w, d, s1, s2.as_register()); + else stf(w, d, s1, s2.as_constant()); +} + inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2) { emit_long( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | rs2(s2) ); } inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13)); } @@ -284,6 +294,7 @@ inline void Assembler::stx(Register d, const Address& a, int offset) { inline void Assembler::stb(Register d, Register s1, RegisterOrConstant s2) { stb(d, Address(s1, s2)); } inline void Assembler::sth(Register d, Register s1, RegisterOrConstant s2) { sth(d, Address(s1, s2)); } +inline void Assembler::stw(Register d, Register s1, RegisterOrConstant s2) { stw(d, Address(s1, s2)); } inline void Assembler::stx(Register d, Register s1, RegisterOrConstant s2) { stx(d, Address(s1, s2)); } inline void Assembler::std(Register d, Register s1, RegisterOrConstant s2) { std(d, Address(s1, s2)); } inline void Assembler::st( Register d, Register s1, RegisterOrConstant s2) { st( d, Address(s1, s2)); } diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index 6dd0a1feb85..4238842cae2 100644 --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -540,14 +540,12 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt, } -// Helper class mostly to avoid passing masm everywhere, and handle store -// displacement overflow logic for LP64 +// Helper class mostly to avoid passing masm everywhere, and handle +// store displacement overflow logic. class AdapterGenerator { MacroAssembler *masm; -#ifdef _LP64 Register Rdisp; void set_Rdisp(Register r) { Rdisp = r; } -#endif // _LP64 void patch_callers_callsite(); void tag_c2i_arg(frame::Tag t, Register base, int st_off, Register scratch); @@ -558,15 +556,18 @@ class AdapterGenerator { return st_off - Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes(); } -#ifdef _LP64 - // On _LP64 argument slot values are loaded first into a register - // because they might not fit into displacement. - Register arg_slot(const int st_off); - Register next_arg_slot(const int st_off); -#else - int arg_slot(const int st_off) { return arg_offset(st_off); } - int next_arg_slot(const int st_off) { return next_arg_offset(st_off); } -#endif // _LP64 + int tag_offset(const int st_off) { return st_off + Interpreter::tag_offset_in_bytes(); } + int next_tag_offset(const int st_off) { + return st_off - Interpreter::stackElementSize() + Interpreter::tag_offset_in_bytes(); + } + + // Argument slot values may be loaded first into a register because + // they might not fit into displacement. + RegisterOrConstant arg_slot(const int st_off); + RegisterOrConstant next_arg_slot(const int st_off); + + RegisterOrConstant tag_slot(const int st_off); + RegisterOrConstant next_tag_slot(const int st_off); // Stores long into offset pointed to by base void store_c2i_long(Register r, Register base, @@ -656,44 +657,42 @@ void AdapterGenerator::patch_callers_callsite() { void AdapterGenerator::tag_c2i_arg(frame::Tag t, Register base, int st_off, Register scratch) { if (TaggedStackInterpreter) { - int tag_off = st_off + Interpreter::tag_offset_in_bytes(); -#ifdef _LP64 - Register tag_slot = Rdisp; - __ set(tag_off, tag_slot); -#else - int tag_slot = tag_off; -#endif // _LP64 + RegisterOrConstant slot = tag_slot(st_off); // have to store zero because local slots can be reused (rats!) if (t == frame::TagValue) { - __ st_ptr(G0, base, tag_slot); + __ st_ptr(G0, base, slot); } else if (t == frame::TagCategory2) { - __ st_ptr(G0, base, tag_slot); - int next_tag_off = st_off - Interpreter::stackElementSize() + - Interpreter::tag_offset_in_bytes(); -#ifdef _LP64 - __ set(next_tag_off, tag_slot); -#else - tag_slot = next_tag_off; -#endif // _LP64 - __ st_ptr(G0, base, tag_slot); + __ st_ptr(G0, base, slot); + __ st_ptr(G0, base, next_tag_slot(st_off)); } else { __ mov(t, scratch); - __ st_ptr(scratch, base, tag_slot); + __ st_ptr(scratch, base, slot); } } } -#ifdef _LP64 -Register AdapterGenerator::arg_slot(const int st_off) { - __ set( arg_offset(st_off), Rdisp); - return Rdisp; + +RegisterOrConstant AdapterGenerator::arg_slot(const int st_off) { + RegisterOrConstant roc(arg_offset(st_off)); + return __ ensure_simm13_or_reg(roc, Rdisp); } -Register AdapterGenerator::next_arg_slot(const int st_off){ - __ set( next_arg_offset(st_off), Rdisp); - return Rdisp; +RegisterOrConstant AdapterGenerator::next_arg_slot(const int st_off) { + RegisterOrConstant roc(next_arg_offset(st_off)); + return __ ensure_simm13_or_reg(roc, Rdisp); } -#endif // _LP64 + + +RegisterOrConstant AdapterGenerator::tag_slot(const int st_off) { + RegisterOrConstant roc(tag_offset(st_off)); + return __ ensure_simm13_or_reg(roc, Rdisp); +} + +RegisterOrConstant AdapterGenerator::next_tag_slot(const int st_off) { + RegisterOrConstant roc(next_tag_offset(st_off)); + return __ ensure_simm13_or_reg(roc, Rdisp); +} + // Stores long into offset pointed to by base void AdapterGenerator::store_c2i_long(Register r, Register base, @@ -1052,9 +1051,7 @@ void AdapterGenerator::gen_i2c_adapter( // Load in argument order going down. const int ld_off = (total_args_passed-i)*Interpreter::stackElementSize(); -#ifdef _LP64 set_Rdisp(G1_scratch); -#endif // _LP64 VMReg r_1 = regs[i].first(); VMReg r_2 = regs[i].second(); @@ -1074,7 +1071,7 @@ void AdapterGenerator::gen_i2c_adapter( #ifdef _LP64 // In V9, longs are given 2 64-bit slots in the interpreter, but the // data is passed in only 1 slot. - Register slot = (sig_bt[i]==T_LONG) ? + RegisterOrConstant slot = (sig_bt[i] == T_LONG) ? next_arg_slot(ld_off) : arg_slot(ld_off); __ ldx(Gargs, slot, r); #else @@ -1092,7 +1089,7 @@ void AdapterGenerator::gen_i2c_adapter( // data is passed in only 1 slot. This code also handles longs that // are passed on the stack, but need a stack-to-stack move through a // spare float register. - Register slot = (sig_bt[i]==T_LONG || sig_bt[i] == T_DOUBLE) ? + RegisterOrConstant slot = (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) ? next_arg_slot(ld_off) : arg_slot(ld_off); __ ldf(FloatRegisterImpl::D, Gargs, slot, r_1->as_FloatRegister()); #else @@ -1109,8 +1106,9 @@ void AdapterGenerator::gen_i2c_adapter( // Convert stack slot to an SP offset int st_off = reg2offset(regs[i].first()) + STACK_BIAS; // Store down the shuffled stack word. Target address _is_ aligned. - if (!r_2->is_valid()) __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), SP, st_off); - else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, st_off); + RegisterOrConstant slot = __ ensure_simm13_or_reg(st_off, Rdisp); + if (!r_2->is_valid()) __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), SP, slot); + else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, slot); } } bool made_space = false; diff --git a/hotspot/test/compiler/6879902/Test6879902.java b/hotspot/test/compiler/6879902/Test6879902.java new file mode 100644 index 00000000000..29c681f61be --- /dev/null +++ b/hotspot/test/compiler/6879902/Test6879902.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6879902 + * @summary CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845 + * + * @run main Test6879902 + */ + +import java.util.Arrays; + +public class Test6879902 { + public static void main(String[] args) { + Object[] oa = new Object[250]; + for (int i = 0; i < 250; i++) { + oa[i] = Integer.valueOf(i); + } + Object[] oa2 = createArray(oa[0], oa[1], oa[2], oa[3], oa[4], oa[5], oa[6], oa[7], oa[8], oa[9], oa[10], oa[11], oa[12], oa[13], oa[14], oa[15], oa[16], oa[17], oa[18], oa[19], oa[20], oa[21], oa[22], oa[23], oa[24], oa[25], oa[26], oa[27], oa[28], oa[29], oa[30], oa[31], oa[32], oa[33], oa[34], oa[35], oa[36], oa[37], oa[38], oa[39], oa[40], oa[41], oa[42], oa[43], oa[44], oa[45], oa[46], oa[47], oa[48], oa[49], oa[50], oa[51], oa[52], oa[53], oa[54], oa[55], oa[56], oa[57], oa[58], oa[59], oa[60], oa[61], oa[62], oa[63], oa[64], oa[65], oa[66], oa[67], oa[68], oa[69], oa[70], oa[71], oa[72], oa[73], oa[74], oa[75], oa[76], oa[77], oa[78], oa[79], oa[80], oa[81], oa[82], oa[83], oa[84], oa[85], oa[86], oa[87], oa[88], oa[89], oa[90], oa[91], oa[92], oa[93], oa[94], oa[95], oa[96], oa[97], oa[98], oa[99], oa[100], oa[101], oa[102], oa[103], oa[104], oa[105], oa[106], oa[107], oa[108], oa[109], oa[110], oa[111], oa[112], oa[113], oa[114], oa[115], oa[116], oa[117], oa[118], oa[119], oa[120], oa[121], oa[122], oa[123], oa[124], oa[125], oa[126], oa[127], oa[128], oa[129], oa[130], oa[131], oa[132], oa[133], oa[134], oa[135], oa[136], oa[137], oa[138], oa[139], oa[140], oa[141], oa[142], oa[143], oa[144], oa[145], oa[146], oa[147], oa[148], oa[149], oa[150], oa[151], oa[152], oa[153], oa[154], oa[155], oa[156], oa[157], oa[158], oa[159], oa[160], oa[161], oa[162], oa[163], oa[164], oa[165], oa[166], oa[167], oa[168], oa[169], oa[170], oa[171], oa[172], oa[173], oa[174], oa[175], oa[176], oa[177], oa[178], oa[179], oa[180], oa[181], oa[182], oa[183], oa[184], oa[185], oa[186], oa[187], oa[188], oa[189], oa[190], oa[191], oa[192], oa[193], oa[194], oa[195], oa[196], oa[197], oa[198], oa[199], oa[200], oa[201], oa[202], oa[203], oa[204], oa[205], oa[206], oa[207], oa[208], oa[209], oa[210], oa[211], oa[212], oa[213], oa[214], oa[215], oa[216], oa[217], oa[218], oa[219], oa[220], oa[221], oa[222], oa[223], oa[224], oa[225], oa[226], oa[227], oa[228], oa[229], oa[230], oa[231], oa[232], oa[233], oa[234], oa[235], oa[236], oa[237], oa[238], oa[239], oa[240], oa[241], oa[242], oa[243], oa[244], oa[245], oa[246], oa[247], oa[248], oa[249]); + if (!Arrays.equals(oa, oa2)) + throw new InternalError("arrays not equal"); + } + + public static Object[] createArray(Object arg0, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14, Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20, Object arg21, Object arg22, Object arg23, Object arg24, Object arg25, Object arg26, Object arg27, Object arg28, Object arg29, Object arg30, Object arg31, Object arg32, Object arg33, Object arg34, Object arg35, Object arg36, Object arg37, Object arg38, Object arg39, Object arg40, Object arg41, Object arg42, Object arg43, Object arg44, Object arg45, Object arg46, Object arg47, Object arg48, Object arg49, Object arg50, Object arg51, Object arg52, Object arg53, Object arg54, Object arg55, Object arg56, Object arg57, Object arg58, Object arg59, Object arg60, Object arg61, Object arg62, Object arg63, Object arg64, Object arg65, Object arg66, Object arg67, Object arg68, Object arg69, Object arg70, Object arg71, Object arg72, Object arg73, Object arg74, Object arg75, Object arg76, Object arg77, Object arg78, Object arg79, Object arg80, Object arg81, Object arg82, Object arg83, Object arg84, Object arg85, Object arg86, Object arg87, Object arg88, Object arg89, Object arg90, Object arg91, Object arg92, Object arg93, Object arg94, Object arg95, Object arg96, Object arg97, Object arg98, Object arg99, Object arg100, Object arg101, Object arg102, Object arg103, Object arg104, Object arg105, Object arg106, Object arg107, Object arg108, Object arg109, Object arg110, Object arg111, Object arg112, Object arg113, Object arg114, Object arg115, Object arg116, Object arg117, Object arg118, Object arg119, Object arg120, Object arg121, Object arg122, Object arg123, Object arg124, Object arg125, Object arg126, Object arg127, Object arg128, Object arg129, Object arg130, Object arg131, Object arg132, Object arg133, Object arg134, Object arg135, Object arg136, Object arg137, Object arg138, Object arg139, Object arg140, Object arg141, Object arg142, Object arg143, Object arg144, Object arg145, Object arg146, Object arg147, Object arg148, Object arg149, Object arg150, Object arg151, Object arg152, Object arg153, Object arg154, Object arg155, Object arg156, Object arg157, Object arg158, Object arg159, Object arg160, Object arg161, Object arg162, Object arg163, Object arg164, Object arg165, Object arg166, Object arg167, Object arg168, Object arg169, Object arg170, Object arg171, Object arg172, Object arg173, Object arg174, Object arg175, Object arg176, Object arg177, Object arg178, Object arg179, Object arg180, Object arg181, Object arg182, Object arg183, Object arg184, Object arg185, Object arg186, Object arg187, Object arg188, Object arg189, Object arg190, Object arg191, Object arg192, Object arg193, Object arg194, Object arg195, Object arg196, Object arg197, Object arg198, Object arg199, Object arg200, Object arg201, Object arg202, Object arg203, Object arg204, Object arg205, Object arg206, Object arg207, Object arg208, Object arg209, Object arg210, Object arg211, Object arg212, Object arg213, Object arg214, Object arg215, Object arg216, Object arg217, Object arg218, Object arg219, Object arg220, Object arg221, Object arg222, Object arg223, Object arg224, Object arg225, Object arg226, Object arg227, Object arg228, Object arg229, Object arg230, Object arg231, Object arg232, Object arg233, Object arg234, Object arg235, Object arg236, Object arg237, Object arg238, Object arg239, Object arg240, Object arg241, Object arg242, Object arg243, Object arg244, Object arg245, Object arg246, Object arg247, Object arg248, Object arg249) { + return new Object[]{ + arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, arg26, arg27, arg28, arg29, arg30, arg31, arg32, arg33, arg34, arg35, arg36, arg37, arg38, arg39, arg40, arg41, arg42, arg43, arg44, arg45, arg46, arg47, arg48, arg49, arg50, arg51, arg52, arg53, arg54, arg55, arg56, arg57, arg58, arg59, arg60, arg61, arg62, arg63, arg64, arg65, arg66, arg67, arg68, arg69, arg70, arg71, arg72, arg73, arg74, arg75, arg76, arg77, arg78, arg79, arg80, arg81, arg82, arg83, arg84, arg85, arg86, arg87, arg88, arg89, arg90, arg91, arg92, arg93, arg94, arg95, arg96, arg97, arg98, arg99, arg100, arg101, arg102, arg103, arg104, arg105, arg106, arg107, arg108, arg109, arg110, arg111, arg112, arg113, arg114, arg115, arg116, arg117, arg118, arg119, arg120, arg121, arg122, arg123, arg124, arg125, arg126, arg127, arg128, arg129, arg130, arg131, arg132, arg133, arg134, arg135, arg136, arg137, arg138, arg139, arg140, arg141, arg142, arg143, arg144, arg145, arg146, arg147, arg148, arg149, arg150, arg151, arg152, arg153, arg154, arg155, arg156, arg157, arg158, arg159, arg160, arg161, arg162, arg163, arg164, arg165, arg166, arg167, arg168, arg169, arg170, arg171, arg172, arg173, arg174, arg175, arg176, arg177, arg178, arg179, arg180, arg181, arg182, arg183, arg184, arg185, arg186, arg187, arg188, arg189, arg190, arg191, arg192, arg193, arg194, arg195, arg196, arg197, arg198, arg199, arg200, arg201, arg202, arg203, arg204, arg205, arg206, arg207, arg208, arg209, arg210, arg211, arg212, arg213, arg214, arg215, arg216, arg217, arg218, arg219, arg220, arg221, arg222, arg223, arg224, arg225, arg226, arg227, arg228, arg229, arg230, arg231, arg232, arg233, arg234, arg235, arg236, arg237, arg238, arg239, arg240, arg241, arg242, arg243, arg244, arg245, arg246, arg247, arg248, arg249}; + } +} From 930f3d4570dd02843cf75bb57a2c970fbd2c22f2 Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Tue, 6 Oct 2009 10:15:38 -0700 Subject: [PATCH 026/172] 6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC Fix problem with the double register encodings in sparc.ad Reviewed-by: never, jrose --- .../src/cpu/sparc/vm/sharedRuntime_sparc.cpp | 13 +- hotspot/src/cpu/sparc/vm/sparc.ad | 64 +++---- .../test/compiler/6880034/Test6880034.java | 163 ++++++++++++++++++ 3 files changed, 201 insertions(+), 39 deletions(-) create mode 100644 hotspot/test/compiler/6880034/Test6880034.java diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index 4238842cae2..f4063e128e4 100644 --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -107,7 +107,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_ // are saved in register windows - I's and L's in the caller's frame and O's in the stub frame // (as the stub's I's) when the runtime routine called by the stub creates its frame. int i; - // Always make the frame size 16 bytr aligned. + // Always make the frame size 16 byte aligned. int frame_size = round_to(additional_frame_words + register_save_size, 16); // OopMap frame size is in c2 stack slots (sizeof(jint)) not bytes or words int frame_size_in_slots = frame_size / sizeof(jint); @@ -201,15 +201,14 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_ __ stx(G5, SP, ccr_offset+STACK_BIAS); __ stxfsr(SP, fsr_offset+STACK_BIAS); - // Save all the FP registers + // Save all the FP registers: 32 doubles (32 floats correspond to the 2 halves of the first 16 doubles) int offset = d00_offset; - for( int i=0; i<64; i+=2 ) { + for( int i=0; iset_callee_saved(VMRegImpl::stack2reg(offset>>2), f->as_VMReg()); - if (true) { - map->set_callee_saved(VMRegImpl::stack2reg((offset + sizeof(float))>>2), f->as_VMReg()->next()); - } + map->set_callee_saved(VMRegImpl::stack2reg((offset + sizeof(float))>>2), f->as_VMReg()->next()); offset += sizeof(double); } @@ -224,7 +223,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_ void RegisterSaver::restore_live_registers(MacroAssembler* masm) { // Restore all the FP registers - for( int i=0; i<64; i+=2 ) { + for( int i=0; ias_VMReg()); // I believe we can't handle callee-save doubles D32 and up until // the place in the sparc stack crawler that asserts on the 255 is // fixed up. -reg_def R_D32x(SOC, SOC, Op_RegD,255, F32->as_VMReg()); -reg_def R_D32 (SOC, SOC, Op_RegD, 1, F32->as_VMReg()->next()); -reg_def R_D34x(SOC, SOC, Op_RegD,255, F34->as_VMReg()); -reg_def R_D34 (SOC, SOC, Op_RegD, 3, F34->as_VMReg()->next()); -reg_def R_D36x(SOC, SOC, Op_RegD,255, F36->as_VMReg()); -reg_def R_D36 (SOC, SOC, Op_RegD, 5, F36->as_VMReg()->next()); -reg_def R_D38x(SOC, SOC, Op_RegD,255, F38->as_VMReg()); -reg_def R_D38 (SOC, SOC, Op_RegD, 7, F38->as_VMReg()->next()); -reg_def R_D40x(SOC, SOC, Op_RegD,255, F40->as_VMReg()); -reg_def R_D40 (SOC, SOC, Op_RegD, 9, F40->as_VMReg()->next()); -reg_def R_D42x(SOC, SOC, Op_RegD,255, F42->as_VMReg()); -reg_def R_D42 (SOC, SOC, Op_RegD, 11, F42->as_VMReg()->next()); -reg_def R_D44x(SOC, SOC, Op_RegD,255, F44->as_VMReg()); -reg_def R_D44 (SOC, SOC, Op_RegD, 13, F44->as_VMReg()->next()); -reg_def R_D46x(SOC, SOC, Op_RegD,255, F46->as_VMReg()); -reg_def R_D46 (SOC, SOC, Op_RegD, 15, F46->as_VMReg()->next()); -reg_def R_D48x(SOC, SOC, Op_RegD,255, F48->as_VMReg()); -reg_def R_D48 (SOC, SOC, Op_RegD, 17, F48->as_VMReg()->next()); -reg_def R_D50x(SOC, SOC, Op_RegD,255, F50->as_VMReg()); -reg_def R_D50 (SOC, SOC, Op_RegD, 19, F50->as_VMReg()->next()); -reg_def R_D52x(SOC, SOC, Op_RegD,255, F52->as_VMReg()); -reg_def R_D52 (SOC, SOC, Op_RegD, 21, F52->as_VMReg()->next()); -reg_def R_D54x(SOC, SOC, Op_RegD,255, F54->as_VMReg()); -reg_def R_D54 (SOC, SOC, Op_RegD, 23, F54->as_VMReg()->next()); -reg_def R_D56x(SOC, SOC, Op_RegD,255, F56->as_VMReg()); -reg_def R_D56 (SOC, SOC, Op_RegD, 25, F56->as_VMReg()->next()); -reg_def R_D58x(SOC, SOC, Op_RegD,255, F58->as_VMReg()); -reg_def R_D58 (SOC, SOC, Op_RegD, 27, F58->as_VMReg()->next()); -reg_def R_D60x(SOC, SOC, Op_RegD,255, F60->as_VMReg()); -reg_def R_D60 (SOC, SOC, Op_RegD, 29, F60->as_VMReg()->next()); -reg_def R_D62x(SOC, SOC, Op_RegD,255, F62->as_VMReg()); -reg_def R_D62 (SOC, SOC, Op_RegD, 31, F62->as_VMReg()->next()); +reg_def R_D32 (SOC, SOC, Op_RegD, 1, F32->as_VMReg()); +reg_def R_D32x(SOC, SOC, Op_RegD,255, F32->as_VMReg()->next()); +reg_def R_D34 (SOC, SOC, Op_RegD, 3, F34->as_VMReg()); +reg_def R_D34x(SOC, SOC, Op_RegD,255, F34->as_VMReg()->next()); +reg_def R_D36 (SOC, SOC, Op_RegD, 5, F36->as_VMReg()); +reg_def R_D36x(SOC, SOC, Op_RegD,255, F36->as_VMReg()->next()); +reg_def R_D38 (SOC, SOC, Op_RegD, 7, F38->as_VMReg()); +reg_def R_D38x(SOC, SOC, Op_RegD,255, F38->as_VMReg()->next()); +reg_def R_D40 (SOC, SOC, Op_RegD, 9, F40->as_VMReg()); +reg_def R_D40x(SOC, SOC, Op_RegD,255, F40->as_VMReg()->next()); +reg_def R_D42 (SOC, SOC, Op_RegD, 11, F42->as_VMReg()); +reg_def R_D42x(SOC, SOC, Op_RegD,255, F42->as_VMReg()->next()); +reg_def R_D44 (SOC, SOC, Op_RegD, 13, F44->as_VMReg()); +reg_def R_D44x(SOC, SOC, Op_RegD,255, F44->as_VMReg()->next()); +reg_def R_D46 (SOC, SOC, Op_RegD, 15, F46->as_VMReg()); +reg_def R_D46x(SOC, SOC, Op_RegD,255, F46->as_VMReg()->next()); +reg_def R_D48 (SOC, SOC, Op_RegD, 17, F48->as_VMReg()); +reg_def R_D48x(SOC, SOC, Op_RegD,255, F48->as_VMReg()->next()); +reg_def R_D50 (SOC, SOC, Op_RegD, 19, F50->as_VMReg()); +reg_def R_D50x(SOC, SOC, Op_RegD,255, F50->as_VMReg()->next()); +reg_def R_D52 (SOC, SOC, Op_RegD, 21, F52->as_VMReg()); +reg_def R_D52x(SOC, SOC, Op_RegD,255, F52->as_VMReg()->next()); +reg_def R_D54 (SOC, SOC, Op_RegD, 23, F54->as_VMReg()); +reg_def R_D54x(SOC, SOC, Op_RegD,255, F54->as_VMReg()->next()); +reg_def R_D56 (SOC, SOC, Op_RegD, 25, F56->as_VMReg()); +reg_def R_D56x(SOC, SOC, Op_RegD,255, F56->as_VMReg()->next()); +reg_def R_D58 (SOC, SOC, Op_RegD, 27, F58->as_VMReg()); +reg_def R_D58x(SOC, SOC, Op_RegD,255, F58->as_VMReg()->next()); +reg_def R_D60 (SOC, SOC, Op_RegD, 29, F60->as_VMReg()); +reg_def R_D60x(SOC, SOC, Op_RegD,255, F60->as_VMReg()->next()); +reg_def R_D62 (SOC, SOC, Op_RegD, 31, F62->as_VMReg()); +reg_def R_D62x(SOC, SOC, Op_RegD,255, F62->as_VMReg()->next()); // ---------------------------- diff --git a/hotspot/test/compiler/6880034/Test6880034.java b/hotspot/test/compiler/6880034/Test6880034.java new file mode 100644 index 00000000000..bc69282ee02 --- /dev/null +++ b/hotspot/test/compiler/6880034/Test6880034.java @@ -0,0 +1,163 @@ +/* + * Copyright 2009 SAP AG. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6880034 + * @summary SIGBUS during deoptimisation at a safepoint on 64bit-SPARC + * + * @run main/othervm -Xcomp -Xbatch -XX:CompileCommand=compileonly,Test6880034,deopt_compiledframe_at_safepoint -XX:+PrintCompilation Test6880034 + */ + + + +// This test provokes a deoptimisation at a safepoint. +// +// It achieves this by compiling the method 'deopt_compiledframe_at_safepoint' +// before its first usage at a point in time when a call to the virtual method +// A::doSomething() from within 'deopt_compiledframe_at_safepoint' can be +// optimised to a static call because class A has no descendants. +// +// Later, when deopt_compiledframe_at_safepoint() is running, class B which +// extends A and overrides the virtual method "doSomething()", is loaded +// asynchronously in another thread. This makes the compiled code of +// 'deopt_compiledframe_at_safepoint' invalid and triggers a deoptimisation of +// the frame where 'deopt_compiledframe_at_safepoint' is running in a +// loop. +// +// The deoptimisation leads to a SIGBUS on 64-bit server VMs on SPARC and to +// an incorrect result on 32-bit server VMs on SPARC due to a regression +// introduced by the change: "6420645: Create a vm that uses compressed oops +// for up to 32gb heapsizes" +// (http://hg.openjdk.java.net/jdk7/jdk7/hotspot/rev/ba764ed4b6f2). Further +// investigation showed that change 6420645 is not really the root cause of +// this error but only reveals a problem with the float register encodings in +// sparc.ad which was hidden until now. +// +// Notice that for this test to fail in jtreg it is crucial that +// deopt_compiledframe_at_safepoint() runs in the main thread. Otherwise a +// crash in deopt_compiledframe_at_safepoint() will not be detected as a test +// failure by jtreg. +// +// Author: Volker H. Simonis + +class A { + public int doSomething() { + return 0; + } +} + +class B extends A { + public B() {} + // override 'A::doSomething()' + public int doSomething() { + return 1; + } +} + +class G { + public static volatile A a = new A(); + + // Change 'a' to point to a 'B' object + public static void setAtoB() { + try { + a = (A) ClassLoader. + getSystemClassLoader(). + loadClass("B"). + getConstructor(new Class[] {}). + newInstance(new Object[] {}); + } + catch (Exception e) { + System.out.println(e); + } + } +} + +public class Test6880034 { + + public static volatile boolean is_in_loop = false; + public static volatile boolean stop_while_loop = false; + + public static double deopt_compiledframe_at_safepoint() { + // This will be an optimised static call to A::doSomething() until we load "B" + int i = G.a.doSomething(); + + // Need more than 16 'double' locals in this frame + double local1 = 1; + double local2 = 2; + double local3 = 3; + double local4 = 4; + double local5 = 5; + double local6 = 6; + double local7 = 7; + double local8 = 8; + + long k = 0; + // Once we load "B", this method will be made 'not entrant' and deoptimised + // at the safepoint which is at the end of this loop. + while (!stop_while_loop) { + if (k == 1) local1 += i; + if (k == 2) local2 += i; + if (k == 3) local3 += i; + if (k == 4) local4 += i; + if (k == 5) local5 += i; + if (k == 6) local6 += i; + if (k == 7) local7 += i; + if (k == 8) local8 += i; + + // Tell the world that we're now running wild in the loop + if (k++ == 20000) is_in_loop = true; + } + + return + local1 + local2 + local3 + local4 + + local5 + local6 + local7 + local8 + i; + } + + public static void main(String[] args) { + + // Just to resolve G before we compile deopt_compiledframe_at_safepoint() + G g = new G(); + + // Asynchronous thread which will eventually invalidate the code for + // deopt_compiledframe_at_safepoint() and therefore triggering a + // deoptimisation of that method. + new Thread() { + public void run() { + while (!is_in_loop) { + // Wait until the loop is running + } + // Load class 'B' asynchronously.. + G.setAtoB(); + // ..and stop the loop + stop_while_loop = true; + } + }.start(); + + // Run the loop in deopt_compiledframe_at_safepoint() + double retVal = deopt_compiledframe_at_safepoint(); + + System.out.println(retVal == 36 ? "OK" : "ERROR : " + retVal); + if (retVal != 36) throw new RuntimeException(); + } +} From 0835f0c4df23a05eadc0bc0e70dcabbc02317ffd Mon Sep 17 00:00:00 2001 From: Antonios Printezis Date: Wed, 7 Oct 2009 09:42:18 -0400 Subject: [PATCH 027/172] 6888316: G1: has_aborted() || _cm->region_stack_empty() fails Remove incorrect guarantee. Reviewed-by: apetrusenko, iveresov --- .../src/share/vm/gc_implementation/g1/concurrentMark.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 59ba0f59c84..2ed4c6700d2 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -3416,13 +3416,6 @@ void CMTask::drain_region_stack(BitMapClosure* bc) { _region_finger = NULL; } - // We only push regions on the region stack during evacuation - // pauses. So if we come out the above iteration because we region - // stack is empty, it will remain empty until the next yield - // point. So, the guarantee below is safe. - guarantee( has_aborted() || _cm->region_stack_empty(), - "only way to exit the loop" ); - if (_cm->verbose_low()) gclog_or_tty->print_cr("[%d] drained region stack, size = %d", _task_id, _cm->region_stack_size()); From 9288a186396e27f1668cdc1a576eeede35ce3553 Mon Sep 17 00:00:00 2001 From: Antonios Printezis Date: Wed, 7 Oct 2009 10:09:57 -0400 Subject: [PATCH 028/172] 6888619: G1: too many guarantees in concurrent marking Change more guarantees in concurrent marking into asserts. Reviewed-by: apetrusenko, iveresov --- .../gc_implementation/g1/concurrentMark.cpp | 262 +++++++++--------- .../gc_implementation/g1/concurrentMark.hpp | 22 +- 2 files changed, 140 insertions(+), 144 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 2ed4c6700d2..656214d45be 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -237,7 +237,7 @@ void CMMarkStack::par_push_arr(oop* ptr_arr, int n) { _index = next_index; for (int i = 0; i < n; i++) { int ind = start + i; - guarantee(ind < _capacity, "By overflow test above."); + assert(ind < _capacity, "By overflow test above."); _base[ind] = ptr_arr[i]; } } @@ -310,12 +310,12 @@ MemRegion CMRegionStack::pop() { if (res == index) { MemRegion mr = _base[next_index]; if (mr.start() != NULL) { - tmp_guarantee_CM( mr.end() != NULL, "invariant" ); - tmp_guarantee_CM( mr.word_size() > 0, "invariant" ); + assert(mr.end() != NULL, "invariant"); + assert(mr.word_size() > 0, "invariant"); return mr; } else { // that entry was invalidated... let's skip it - tmp_guarantee_CM( mr.end() == NULL, "invariant" ); + assert(mr.end() == NULL, "invariant"); } } // Otherwise, we need to try again. @@ -328,10 +328,10 @@ bool CMRegionStack::invalidate_entries_into_cset() { for (int i = 0; i < _oops_do_bound; ++i) { MemRegion mr = _base[i]; if (mr.start() != NULL) { - tmp_guarantee_CM( mr.end() != NULL, "invariant"); - tmp_guarantee_CM( mr.word_size() > 0, "invariant" ); + assert(mr.end() != NULL, "invariant"); + assert(mr.word_size() > 0, "invariant"); HeapRegion* hr = g1h->heap_region_containing(mr.start()); - tmp_guarantee_CM( hr != NULL, "invariant" ); + assert(hr != NULL, "invariant"); if (hr->in_collection_set()) { // The region points into the collection set _base[i] = MemRegion(); @@ -339,7 +339,7 @@ bool CMRegionStack::invalidate_entries_into_cset() { } } else { // that entry was invalidated... let's skip it - tmp_guarantee_CM( mr.end() == NULL, "invariant" ); + assert(mr.end() == NULL, "invariant"); } } return result; @@ -542,7 +542,7 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs, gclog_or_tty->print_cr("CL Sleep Factor %1.4lf", cleanup_sleep_factor()); #endif - guarantee( parallel_marking_threads() > 0, "peace of mind" ); + guarantee(parallel_marking_threads() > 0, "peace of mind"); _parallel_workers = new WorkGang("G1 Parallel Marking Threads", (int) parallel_marking_threads(), false, true); if (_parallel_workers == NULL) @@ -569,8 +569,7 @@ void ConcurrentMark::update_g1_committed(bool force) { return; MemRegion committed = _g1h->g1_committed(); - tmp_guarantee_CM( committed.start() == _heap_start, - "start shouldn't change" ); + assert(committed.start() == _heap_start, "start shouldn't change"); HeapWord* new_end = committed.end(); if (new_end > _heap_end) { // The heap has been expanded. @@ -592,9 +591,10 @@ void ConcurrentMark::reset() { _heap_start = committed.start(); _heap_end = committed.end(); - guarantee( _heap_start != NULL && - _heap_end != NULL && - _heap_start < _heap_end, "heap bounds should look ok" ); + // Separated the asserts so that we know which one fires. + assert(_heap_start != NULL, "heap bounds should look ok"); + assert(_heap_end != NULL, "heap bounds should look ok"); + assert(_heap_start < _heap_end, "heap bounds should look ok"); // reset all the marking data structures and any necessary flags clear_marking_state(); @@ -614,7 +614,7 @@ void ConcurrentMark::reset() { } void ConcurrentMark::set_phase(size_t active_tasks, bool concurrent) { - guarantee( active_tasks <= _max_task_num, "we should not have more" ); + assert(active_tasks <= _max_task_num, "we should not have more"); _active_tasks = active_tasks; // Need to update the three data structures below according to the @@ -634,8 +634,8 @@ void ConcurrentMark::set_phase(size_t active_tasks, bool concurrent) { // We currently assume that the concurrent flag has been set to // false before we start remark. At this point we should also be // in a STW phase. - guarantee( !concurrent_marking_in_progress(), "invariant" ); - guarantee( _finger == _heap_end, "only way to get here" ); + assert(!concurrent_marking_in_progress(), "invariant"); + assert(_finger == _heap_end, "only way to get here"); update_g1_committed(true); } } @@ -933,8 +933,8 @@ void ConcurrentMark::grayRoot(oop p) { // initial-mark that the committed space is expanded during the // pause without CM observing this change. So the assertions below // is a bit conservative; but better than nothing. - tmp_guarantee_CM( _g1h->g1_committed().contains(addr), - "address should be within the heap bounds" ); + assert(_g1h->g1_committed().contains(addr), + "address should be within the heap bounds"); if (!_nextMarkBitMap->isMarked(addr)) _nextMarkBitMap->parMark(addr); @@ -960,12 +960,15 @@ void ConcurrentMark::grayRegionIfNecessary(MemRegion mr) { if (mr.start() < finger) { // The finger is always heap region aligned and it is not possible // for mr to span heap regions. - tmp_guarantee_CM( mr.end() <= finger, "invariant" ); + assert(mr.end() <= finger, "invariant"); - tmp_guarantee_CM( mr.start() <= mr.end() && - _heap_start <= mr.start() && - mr.end() <= _heap_end, - "region boundaries should fall within the committed space" ); + // Separated the asserts so that we know which one fires. + assert(mr.start() <= mr.end(), + "region boundaries should fall within the committed space"); + assert(_heap_start <= mr.start(), + "region boundaries should fall within the committed space"); + assert(mr.end() <= _heap_end, + "region boundaries should fall within the committed space"); if (verbose_low()) gclog_or_tty->print_cr("[global] region ["PTR_FORMAT", "PTR_FORMAT") " "below the finger, pushing it", @@ -1014,14 +1017,14 @@ private: public: void work(int worker_i) { - guarantee( Thread::current()->is_ConcurrentGC_thread(), - "this should only be done by a conc GC thread" ); + assert(Thread::current()->is_ConcurrentGC_thread(), + "this should only be done by a conc GC thread"); double start_vtime = os::elapsedVTime(); ConcurrentGCThread::stsJoin(); - guarantee( (size_t)worker_i < _cm->active_tasks(), "invariant" ); + assert((size_t) worker_i < _cm->active_tasks(), "invariant"); CMTask* the_task = _cm->task(worker_i); the_task->record_start_time(); if (!_cm->has_aborted()) { @@ -1059,7 +1062,7 @@ public: } while (!_cm->has_aborted() && the_task->has_aborted()); } the_task->record_end_time(); - guarantee( !the_task->has_aborted() || _cm->has_aborted(), "invariant" ); + guarantee(!the_task->has_aborted() || _cm->has_aborted(), "invariant"); ConcurrentGCThread::stsLeave(); @@ -1182,8 +1185,7 @@ class CalcLiveObjectsClosure: public HeapRegionClosure { void mark_card_num_range(intptr_t start_card_num, intptr_t last_card_num) { for (intptr_t i = start_card_num; i <= last_card_num; i++) { #if CARD_BM_TEST_MODE - guarantee(_card_bm->at(i - _bottom_card_num), - "Should already be set."); + guarantee(_card_bm->at(i - _bottom_card_num), "Should already be set."); #else _card_bm->par_at_put(i - _bottom_card_num, 1); #endif @@ -1442,7 +1444,7 @@ public: } assert(calccl.complete(), "Shouldn't have yielded!"); - guarantee( (size_t)i < _n_workers, "invariant" ); + assert((size_t) i < _n_workers, "invariant"); _live_bytes[i] = calccl.tot_live(); _used_bytes[i] = calccl.tot_used(); } @@ -1774,14 +1776,14 @@ void ConcurrentMark::completeCleanup() { hd->rem_set()->clear(); HeapRegion* next_hd = hd->next_from_unclean_list(); (void)list->pop(); - guarantee(list->hd() == next_hd, "how not?"); + assert(list->hd() == next_hd, "how not?"); _g1h->put_region_on_unclean_list(hd); if (!hd->isHumongous()) { // Add this to the _free_regions count by 1. _g1h->finish_free_region_work(0, 0, 1, NULL); } hd = list->hd(); - guarantee(hd == next_hd, "how not?"); + assert(hd == next_hd, "how not?"); } } } @@ -1931,9 +1933,6 @@ void ConcurrentMark::checkpointRootsFinalWork() { g1h->set_par_threads(n_workers); g1h->workers()->run_task(&remarkTask); g1h->set_par_threads(0); - - SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); - guarantee( satb_mq_set.completed_buffers_num() == 0, "invariant" ); } else { G1CollectedHeap::StrongRootsScope srs(g1h); // this is remark, so we'll use up all available threads @@ -1945,10 +1944,9 @@ void ConcurrentMark::checkpointRootsFinalWork() { // active_workers will be fewer. The extra ones will just bail out // immediately. remarkTask.work(0); - - SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); - guarantee( satb_mq_set.completed_buffers_num() == 0, "invariant" ); } + SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); + guarantee(satb_mq_set.completed_buffers_num() == 0, "invariant"); print_stats(); @@ -1989,7 +1987,7 @@ public: str = "outside G1 reserved"; else { HeapRegion* hr = _g1h->heap_region_containing(obj); - guarantee( hr != NULL, "invariant" ); + guarantee(hr != NULL, "invariant"); if (hr->obj_allocated_since_prev_marking(obj)) { str = "over TAMS"; if (_bitmap->isMarked((HeapWord*) obj)) @@ -2125,7 +2123,7 @@ void ConcurrentMark::deal_with_reference(oop obj) { HeapWord* objAddr = (HeapWord*) obj; assert(obj->is_oop_or_null(true /* ignore mark word */), "Error"); if (_g1h->is_in_g1_reserved(objAddr)) { - tmp_guarantee_CM( obj != NULL, "is_in_g1_reserved should ensure this" ); + assert(obj != NULL, "is_in_g1_reserved should ensure this"); HeapRegion* hr = _g1h->heap_region_containing(obj); if (_g1h->is_obj_ill(obj, hr)) { if (verbose_high()) @@ -2167,7 +2165,7 @@ void ConcurrentMark::drainAllSATBBuffers() { satb_mq_set.iterate_closure_all_threads(); satb_mq_set.set_closure(NULL); - guarantee( satb_mq_set.completed_buffers_num() == 0, "invariant" ); + assert(satb_mq_set.completed_buffers_num() == 0, "invariant"); } void ConcurrentMark::markPrev(oop p) { @@ -2200,7 +2198,7 @@ ConcurrentMark::claim_region(int task_num) { // _heap_end will not change underneath our feet; it only changes at // yield points. while (finger < _heap_end) { - tmp_guarantee_CM( _g1h->is_in_g1_reserved(finger), "invariant" ); + assert(_g1h->is_in_g1_reserved(finger), "invariant"); // is the gap between reading the finger and doing the CAS too long? @@ -2222,7 +2220,7 @@ ConcurrentMark::claim_region(int task_num) { // notice that _finger == end cannot be guaranteed here since, // someone else might have moved the finger even further - guarantee( _finger >= end, "the finger should have moved forward" ); + assert(_finger >= end, "the finger should have moved forward"); if (verbose_low()) gclog_or_tty->print_cr("[%d] we were successful with region = " @@ -2234,8 +2232,8 @@ ConcurrentMark::claim_region(int task_num) { "returning it ", task_num, curr_region); return curr_region; } else { - tmp_guarantee_CM( limit == bottom, - "the region limit should be at bottom" ); + assert(limit == bottom, + "the region limit should be at bottom"); if (verbose_low()) gclog_or_tty->print_cr("[%d] region "PTR_FORMAT" is empty, " "returning NULL", task_num, curr_region); @@ -2244,7 +2242,7 @@ ConcurrentMark::claim_region(int task_num) { return NULL; } } else { - guarantee( _finger > finger, "the finger should have moved forward" ); + assert(_finger > finger, "the finger should have moved forward"); if (verbose_low()) gclog_or_tty->print_cr("[%d] somebody else moved the finger, " "global finger = "PTR_FORMAT", " @@ -2282,7 +2280,7 @@ void ConcurrentMark::oops_do(OopClosure* cl) { if (_regionStack.invalidate_entries_into_cset()) { // otherwise, any gray objects copied during the evacuation pause // might not be visited. - guarantee( _should_gray_objects, "invariant" ); + assert(_should_gray_objects, "invariant"); } } @@ -2715,12 +2713,12 @@ public: bool do_bit(size_t offset) { HeapWord* addr = _nextMarkBitMap->offsetToHeapWord(offset); - tmp_guarantee_CM( _nextMarkBitMap->isMarked(addr), "invariant" ); - tmp_guarantee_CM( addr < _cm->finger(), "invariant" ); + assert(_nextMarkBitMap->isMarked(addr), "invariant"); + assert( addr < _cm->finger(), "invariant"); if (_scanning_heap_region) { statsOnly( _task->increase_objs_found_on_bitmap() ); - tmp_guarantee_CM( addr >= _task->finger(), "invariant" ); + assert(addr >= _task->finger(), "invariant"); // We move that task's local finger along. _task->move_finger_to(addr); } else { @@ -2765,8 +2763,9 @@ public: virtual void do_oop( oop* p) { do_oop_work(p); } template void do_oop_work(T* p) { - tmp_guarantee_CM( _g1h->is_in_g1_reserved((HeapWord*) p), "invariant" ); - tmp_guarantee_CM( !_g1h->heap_region_containing((HeapWord*) p)->is_on_free_list(), "invariant" ); + assert(_g1h->is_in_g1_reserved((HeapWord*) p), "invariant"); + assert(!_g1h->heap_region_containing((HeapWord*) p)->is_on_free_list(), + "invariant"); oop obj = oopDesc::load_decode_heap_oop(p); if (_cm->verbose_high()) @@ -2783,8 +2782,11 @@ public: }; void CMTask::setup_for_region(HeapRegion* hr) { - tmp_guarantee_CM( hr != NULL && !hr->continuesHumongous(), - "claim_region() should have filtered out continues humongous regions" ); + // Separated the asserts so that we know which one fires. + assert(hr != NULL, + "claim_region() should have filtered out continues humongous regions"); + assert(!hr->continuesHumongous(), + "claim_region() should have filtered out continues humongous regions"); if (_cm->verbose_low()) gclog_or_tty->print_cr("[%d] setting up for region "PTR_FORMAT, @@ -2812,9 +2814,9 @@ void CMTask::update_region_limit() { // as the region is not supposed to be empty in the first place) _finger = bottom; } else if (limit >= _region_limit) { - tmp_guarantee_CM( limit >= _finger, "peace of mind" ); + assert(limit >= _finger, "peace of mind"); } else { - tmp_guarantee_CM( limit < _region_limit, "only way to get here" ); + assert(limit < _region_limit, "only way to get here"); // This can happen under some pretty unusual circumstances. An // evacuation pause empties the region underneath our feet (NTAMS // at bottom). We then do some allocation in the region (NTAMS @@ -2832,7 +2834,7 @@ void CMTask::update_region_limit() { } void CMTask::giveup_current_region() { - tmp_guarantee_CM( _curr_region != NULL, "invariant" ); + assert(_curr_region != NULL, "invariant"); if (_cm->verbose_low()) gclog_or_tty->print_cr("[%d] giving up region "PTR_FORMAT, _task_id, _curr_region); @@ -2850,7 +2852,7 @@ void CMTask::clear_region_fields() { } void CMTask::reset(CMBitMap* nextMarkBitMap) { - guarantee( nextMarkBitMap != NULL, "invariant" ); + guarantee(nextMarkBitMap != NULL, "invariant"); if (_cm->verbose_low()) gclog_or_tty->print_cr("[%d] resetting", _task_id); @@ -2916,7 +2918,7 @@ void CMTask::deal_with_reference(oop obj) { HeapWord* objAddr = (HeapWord*) obj; assert(obj->is_oop_or_null(true /* ignore mark word */), "Error"); if (_g1h->is_in_g1_reserved(objAddr)) { - tmp_guarantee_CM( obj != NULL, "is_in_g1_reserved should ensure this" ); + assert(obj != NULL, "is_in_g1_reserved should ensure this"); HeapRegion* hr = _g1h->heap_region_containing(obj); if (_g1h->is_obj_ill(obj, hr)) { if (_cm->verbose_high()) @@ -2977,10 +2979,11 @@ void CMTask::deal_with_reference(oop obj) { void CMTask::push(oop obj) { HeapWord* objAddr = (HeapWord*) obj; - tmp_guarantee_CM( _g1h->is_in_g1_reserved(objAddr), "invariant" ); - tmp_guarantee_CM( !_g1h->heap_region_containing(objAddr)->is_on_free_list(), "invariant" ); - tmp_guarantee_CM( !_g1h->is_obj_ill(obj), "invariant" ); - tmp_guarantee_CM( _nextMarkBitMap->isMarked(objAddr), "invariant" ); + assert(_g1h->is_in_g1_reserved(objAddr), "invariant"); + assert(!_g1h->heap_region_containing(objAddr)->is_on_free_list(), + "invariant"); + assert(!_g1h->is_obj_ill(obj), "invariant"); + assert(_nextMarkBitMap->isMarked(objAddr), "invariant"); if (_cm->verbose_high()) gclog_or_tty->print_cr("[%d] pushing "PTR_FORMAT, _task_id, (void*) obj); @@ -2999,7 +3002,7 @@ void CMTask::push(oop obj) { // stack, we should have definitely removed some entries from the // local queue. So, there must be space on it. bool success = _task_queue->push(obj); - tmp_guarantee_CM( success, "invariant" ); + assert(success, "invariant"); } statsOnly( int tmp_size = _task_queue->size(); @@ -3009,9 +3012,9 @@ void CMTask::push(oop obj) { } void CMTask::reached_limit() { - tmp_guarantee_CM( _words_scanned >= _words_scanned_limit || - _refs_reached >= _refs_reached_limit , - "shouldn't have been called otherwise" ); + assert(_words_scanned >= _words_scanned_limit || + _refs_reached >= _refs_reached_limit , + "shouldn't have been called otherwise"); regular_clock_call(); } @@ -3169,8 +3172,8 @@ void CMTask::get_entries_from_global_stack() { oop buffer[global_stack_transfer_size]; int n; _cm->mark_stack_pop(buffer, global_stack_transfer_size, &n); - tmp_guarantee_CM( n <= global_stack_transfer_size, - "we should not pop more than the given limit" ); + assert(n <= global_stack_transfer_size, + "we should not pop more than the given limit"); if (n > 0) { // yes, we did actually pop at least one entry @@ -3182,7 +3185,7 @@ void CMTask::get_entries_from_global_stack() { bool success = _task_queue->push(buffer[i]); // We only call this when the local queue is empty or under a // given target limit. So, we do not expect this push to fail. - tmp_guarantee_CM( success, "invariant" ); + assert(success, "invariant"); } statsOnly( int tmp_size = _task_queue->size(); @@ -3222,10 +3225,9 @@ void CMTask::drain_local_queue(bool partially) { gclog_or_tty->print_cr("[%d] popped "PTR_FORMAT, _task_id, (void*) obj); - tmp_guarantee_CM( _g1h->is_in_g1_reserved((HeapWord*) obj), - "invariant" ); - tmp_guarantee_CM( !_g1h->heap_region_containing(obj)->is_on_free_list(), - "invariant" ); + assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" ); + assert(!_g1h->heap_region_containing(obj)->is_on_free_list(), + "invariant"); scan_object(obj); @@ -3247,7 +3249,7 @@ void CMTask::drain_global_stack(bool partially) { // We have a policy to drain the local queue before we attempt to // drain the global stack. - tmp_guarantee_CM( partially || _task_queue->size() == 0, "invariant" ); + assert(partially || _task_queue->size() == 0, "invariant"); // Decide what the target size is, depending whether we're going to // drain it partially (so that other tasks can steal if they run out @@ -3328,9 +3330,9 @@ void CMTask::drain_satb_buffers() { _draining_satb_buffers = false; - tmp_guarantee_CM( has_aborted() || - concurrent() || - satb_mq_set.completed_buffers_num() == 0, "invariant" ); + assert(has_aborted() || + concurrent() || + satb_mq_set.completed_buffers_num() == 0, "invariant"); if (ParallelGCThreads > 0) satb_mq_set.set_par_closure(_task_id, NULL); @@ -3346,8 +3348,8 @@ void CMTask::drain_region_stack(BitMapClosure* bc) { if (has_aborted()) return; - tmp_guarantee_CM( _region_finger == NULL, - "it should be NULL when we're not scanning a region" ); + assert(_region_finger == NULL, + "it should be NULL when we're not scanning a region"); if (!_cm->region_stack_empty()) { if (_cm->verbose_low()) @@ -3363,12 +3365,12 @@ void CMTask::drain_region_stack(BitMapClosure* bc) { gclog_or_tty->print_cr("[%d] we are scanning region " "["PTR_FORMAT", "PTR_FORMAT")", _task_id, mr.start(), mr.end()); - tmp_guarantee_CM( mr.end() <= _cm->finger(), - "otherwise the region shouldn't be on the stack" ); + assert(mr.end() <= _cm->finger(), + "otherwise the region shouldn't be on the stack"); assert(!mr.is_empty(), "Only non-empty regions live on the region stack"); if (_nextMarkBitMap->iterate(bc, mr)) { - tmp_guarantee_CM( !has_aborted(), - "cannot abort the task without aborting the bitmap iteration" ); + assert(!has_aborted(), + "cannot abort the task without aborting the bitmap iteration"); // We finished iterating over the region without aborting. regular_clock_call(); @@ -3380,14 +3382,14 @@ void CMTask::drain_region_stack(BitMapClosure* bc) { statsOnly(if (mr.start() != NULL) ++_region_stack_pops ); } } else { - guarantee( has_aborted(), "currently the only way to do so" ); + assert(has_aborted(), "currently the only way to do so"); // The only way to abort the bitmap iteration is to return // false from the do_bit() method. However, inside the // do_bit() method we move the _region_finger to point to the // object currently being looked at. So, if we bail out, we // have definitely set _region_finger to something non-null. - guarantee( _region_finger != NULL, "invariant" ); + assert(_region_finger != NULL, "invariant"); // The iteration was actually aborted. So now _region_finger // points to the address of the object we last scanned. If we @@ -3573,21 +3575,21 @@ void CMTask::print_stats() { *****************************************************************************/ void CMTask::do_marking_step(double time_target_ms) { - guarantee( time_target_ms >= 1.0, "minimum granularity is 1ms" ); - guarantee( concurrent() == _cm->concurrent(), "they should be the same" ); + assert(time_target_ms >= 1.0, "minimum granularity is 1ms"); + assert(concurrent() == _cm->concurrent(), "they should be the same"); - guarantee( concurrent() || _cm->region_stack_empty(), - "the region stack should have been cleared before remark" ); - guarantee( _region_finger == NULL, - "this should be non-null only when a region is being scanned" ); + assert(concurrent() || _cm->region_stack_empty(), + "the region stack should have been cleared before remark"); + assert(_region_finger == NULL, + "this should be non-null only when a region is being scanned"); G1CollectorPolicy* g1_policy = _g1h->g1_policy(); - guarantee( _task_queues != NULL, "invariant" ); - guarantee( _task_queue != NULL, "invariant" ); - guarantee( _task_queues->queue(_task_id) == _task_queue, "invariant" ); + assert(_task_queues != NULL, "invariant"); + assert(_task_queue != NULL, "invariant"); + assert(_task_queues->queue(_task_id) == _task_queue, "invariant"); - guarantee( !_claimed, - "only one thread should claim this task at any one time" ); + assert(!_claimed, + "only one thread should claim this task at any one time"); // OK, this doesn't safeguard again all possible scenarios, as it is // possible for two threads to set the _claimed flag at the same @@ -3658,9 +3660,8 @@ void CMTask::do_marking_step(double time_target_ms) { do { if (!has_aborted() && _curr_region != NULL) { // This means that we're already holding on to a region. - tmp_guarantee_CM( _finger != NULL, - "if region is not NULL, then the finger " - "should not be NULL either" ); + assert(_finger != NULL, "if region is not NULL, then the finger " + "should not be NULL either"); // We might have restarted this task after an evacuation pause // which might have evacuated the region we're holding on to @@ -3692,13 +3693,13 @@ void CMTask::do_marking_step(double time_target_ms) { giveup_current_region(); regular_clock_call(); } else { - guarantee( has_aborted(), "currently the only way to do so" ); + assert(has_aborted(), "currently the only way to do so"); // The only way to abort the bitmap iteration is to return // false from the do_bit() method. However, inside the // do_bit() method we move the _finger to point to the // object currently being looked at. So, if we bail out, we // have definitely set _finger to something non-null. - guarantee( _finger != NULL, "invariant" ); + assert(_finger != NULL, "invariant"); // Region iteration was actually aborted. So now _finger // points to the address of the object we last scanned. If we @@ -3725,9 +3726,10 @@ void CMTask::do_marking_step(double time_target_ms) { while (!has_aborted() && _curr_region == NULL && !_cm->out_of_regions()) { // We are going to try to claim a new region. We should have // given up on the previous one. - tmp_guarantee_CM( _curr_region == NULL && - _finger == NULL && - _region_limit == NULL, "invariant" ); + // Separated the asserts so that we know which one fires. + assert(_curr_region == NULL, "invariant"); + assert(_finger == NULL, "invariant"); + assert(_region_limit == NULL, "invariant"); if (_cm->verbose_low()) gclog_or_tty->print_cr("[%d] trying to claim a new region", _task_id); HeapRegion* claimed_region = _cm->claim_region(_task_id); @@ -3741,7 +3743,7 @@ void CMTask::do_marking_step(double time_target_ms) { _task_id, claimed_region); setup_for_region(claimed_region); - tmp_guarantee_CM( _curr_region == claimed_region, "invariant" ); + assert(_curr_region == claimed_region, "invariant"); } // It is important to call the regular clock here. It might take // a while to claim a region if, for example, we hit a large @@ -3752,8 +3754,8 @@ void CMTask::do_marking_step(double time_target_ms) { } if (!has_aborted() && _curr_region == NULL) { - tmp_guarantee_CM( _cm->out_of_regions(), - "at this point we should be out of regions" ); + assert(_cm->out_of_regions(), + "at this point we should be out of regions"); } } while ( _curr_region != NULL && !has_aborted()); @@ -3762,8 +3764,8 @@ void CMTask::do_marking_step(double time_target_ms) { // tasks might be pushing objects to it concurrently. We also cannot // check if the region stack is empty because if a thread is aborting // it can push a partially done region back. - tmp_guarantee_CM( _cm->out_of_regions(), - "at this point we should be out of regions" ); + assert(_cm->out_of_regions(), + "at this point we should be out of regions"); if (_cm->verbose_low()) gclog_or_tty->print_cr("[%d] all regions claimed", _task_id); @@ -3787,8 +3789,8 @@ void CMTask::do_marking_step(double time_target_ms) { // tasks might be pushing objects to it concurrently. We also cannot // check if the region stack is empty because if a thread is aborting // it can push a partially done region back. - guarantee( _cm->out_of_regions() && - _task_queue->size() == 0, "only way to reach here" ); + assert(_cm->out_of_regions() && _task_queue->size() == 0, + "only way to reach here"); if (_cm->verbose_low()) gclog_or_tty->print_cr("[%d] starting to steal", _task_id); @@ -3804,8 +3806,8 @@ void CMTask::do_marking_step(double time_target_ms) { statsOnly( ++_steals ); - tmp_guarantee_CM( _nextMarkBitMap->isMarked((HeapWord*) obj), - "any stolen object should be marked" ); + assert(_nextMarkBitMap->isMarked((HeapWord*) obj), + "any stolen object should be marked"); scan_object(obj); // And since we're towards the end, let's totally drain the @@ -3825,8 +3827,9 @@ void CMTask::do_marking_step(double time_target_ms) { // tasks might be concurrently pushing objects on it. We also cannot // check if the region stack is empty because if a thread is aborting // it can push a partially done region back. - guarantee( _cm->out_of_regions() && - _task_queue->size() == 0, "only way to reach here" ); + // Separated the asserts so that we know which one fires. + assert(_cm->out_of_regions(), "only way to reach here"); + assert(_task_queue->size() == 0, "only way to reach here"); if (_cm->verbose_low()) gclog_or_tty->print_cr("[%d] starting termination protocol", _task_id); @@ -3846,7 +3849,7 @@ void CMTask::do_marking_step(double time_target_ms) { if (_task_id == 0) { // let's allow task 0 to do this if (concurrent()) { - guarantee( _cm->concurrent_marking_in_progress(), "invariant" ); + assert(_cm->concurrent_marking_in_progress(), "invariant"); // we need to set this to false before the next // safepoint. This way we ensure that the marking phase // doesn't observe any more heap expansions. @@ -3855,15 +3858,16 @@ void CMTask::do_marking_step(double time_target_ms) { } // We can now guarantee that the global stack is empty, since - // all other tasks have finished. - guarantee( _cm->out_of_regions() && - _cm->region_stack_empty() && - _cm->mark_stack_empty() && - _task_queue->size() == 0 && - !_cm->has_overflown() && - !_cm->mark_stack_overflow() && - !_cm->region_stack_overflow(), - "only way to reach here" ); + // all other tasks have finished. We separated the guarantees so + // that, if a condition is false, we can immediately find out + // which one. + guarantee(_cm->out_of_regions(), "only way to reach here"); + guarantee(_cm->region_stack_empty(), "only way to reach here"); + guarantee(_cm->mark_stack_empty(), "only way to reach here"); + guarantee(_task_queue->size() == 0, "only way to reach here"); + guarantee(!_cm->has_overflown(), "only way to reach here"); + guarantee(!_cm->mark_stack_overflow(), "only way to reach here"); + guarantee(!_cm->region_stack_overflow(), "only way to reach here"); if (_cm->verbose_low()) gclog_or_tty->print_cr("[%d] all tasks terminated", _task_id); @@ -3958,8 +3962,8 @@ CMTask::CMTask(int task_id, _task_queue(task_queue), _task_queues(task_queues), _oop_closure(NULL) { - guarantee( task_queue != NULL, "invariant" ); - guarantee( task_queues != NULL, "invariant" ); + guarantee(task_queue != NULL, "invariant"); + guarantee(task_queues != NULL, "invariant"); statsOnly( _clock_due_to_scanning = 0; _clock_due_to_marking = 0 ); diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp index eae6ef94bfd..8cf0207dbb3 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp @@ -295,12 +295,6 @@ do { \ } while (0) #endif // _MARKING_STATS_ -// Some extra guarantees that I like to also enable in optimised mode -// when debugging. If you want to enable them, comment out the assert -// macro and uncomment out the guaratee macro -// #define tmp_guarantee_CM(expr, str) guarantee(expr, str) -#define tmp_guarantee_CM(expr, str) assert(expr, str) - typedef enum { no_verbose = 0, // verbose turned off stats_verbose, // only prints stats at the end of marking @@ -485,15 +479,15 @@ protected: // Returns the task with the given id CMTask* task(int id) { - guarantee( 0 <= id && id < (int) _active_tasks, "task id not within " - "active bounds" ); + assert(0 <= id && id < (int) _active_tasks, + "task id not within active bounds"); return _tasks[id]; } // Returns the task queue with the given id CMTaskQueue* task_queue(int id) { - guarantee( 0 <= id && id < (int) _active_tasks, "task queue id not within " - "active bounds" ); + assert(0 <= id && id < (int) _active_tasks, + "task queue id not within active bounds"); return (CMTaskQueue*) _task_queues->queue(id); } @@ -961,8 +955,7 @@ public: // It scans an object and visits its children. void scan_object(oop obj) { - tmp_guarantee_CM( _nextMarkBitMap->isMarked((HeapWord*) obj), - "invariant" ); + assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant"); if (_cm->verbose_high()) gclog_or_tty->print_cr("[%d] we're scanning object "PTR_FORMAT, @@ -1001,14 +994,13 @@ public: // moves the local finger to a new location inline void move_finger_to(HeapWord* new_finger) { - tmp_guarantee_CM( new_finger >= _finger && new_finger < _region_limit, - "invariant" ); + assert(new_finger >= _finger && new_finger < _region_limit, "invariant"); _finger = new_finger; } // moves the region finger to a new location inline void move_region_finger_to(HeapWord* new_finger) { - tmp_guarantee_CM( new_finger < _cm->finger(), "invariant" ); + assert(new_finger < _cm->finger(), "invariant"); _region_finger = new_finger; } From 9681f68f38af605de8c1db9349fb6955e5202f36 Mon Sep 17 00:00:00 2001 From: Bob Vandette Date: Wed, 7 Oct 2009 09:48:42 -0400 Subject: [PATCH 029/172] 6888847: TaskQueue needs release_store() for correctness on RMO machines See title. Reviewed-by: jmasa, ysr, jcoomes, iveresov, tonyp --- hotspot/src/share/vm/utilities/taskqueue.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/utilities/taskqueue.hpp b/hotspot/src/share/vm/utilities/taskqueue.hpp index 34ca1668c7f..6b0076b0d8a 100644 --- a/hotspot/src/share/vm/utilities/taskqueue.hpp +++ b/hotspot/src/share/vm/utilities/taskqueue.hpp @@ -207,7 +207,7 @@ bool GenericTaskQueue::push_slow(E t, uint dirty_n_elems) { // Actually means 0, so do the push. uint localBot = _bottom; _elems[localBot] = t; - _bottom = increment_index(localBot); + OrderAccess::release_store(&_bottom, increment_index(localBot)); return true; } return false; @@ -485,7 +485,7 @@ template inline bool GenericTaskQueue::push(E t) { assert((dirty_n_elems >= 0) && (dirty_n_elems < N), "n_elems out of range."); if (dirty_n_elems < max_elems()) { _elems[localBot] = t; - _bottom = increment_index(localBot); + OrderAccess::release_store(&_bottom, increment_index(localBot)); return true; } else { return push_slow(t, dirty_n_elems); From ba951dbf36ace66d7ac40a3859a66b05f11e6673 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 7 Oct 2009 12:43:50 -0700 Subject: [PATCH 030/172] 6875959: CTW fails hotspot/src/share/vm/opto/reg_split.cpp:1087 To break spill ties choose bound live range over unbound to free register or one with smaller cost to spill. Reviewed-by: never, jrose --- hotspot/src/share/vm/opto/chaitin.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp index eb177c8f56c..c16886c3e85 100644 --- a/hotspot/src/share/vm/opto/chaitin.cpp +++ b/hotspot/src/share/vm/opto/chaitin.cpp @@ -985,10 +985,12 @@ void PhaseChaitin::Simplify( ) { uint lo_score = _hi_degree; double score = lrgs(lo_score).score(); double area = lrgs(lo_score)._area; + double cost = lrgs(lo_score)._cost; + bool bound = lrgs(lo_score)._is_bound; // Find cheapest guy debug_only( int lo_no_simplify=0; ); - for( uint i = _hi_degree; i; i = lrgs(i)._next ) { + for( uint i = lrgs(lo_score)._next; i; i = lrgs(i)._next ) { assert( !(*_ifg->_yanked)[i], "" ); // It's just vaguely possible to move hi-degree to lo-degree without // going through a just-lo-degree stage: If you remove a double from @@ -1002,17 +1004,27 @@ void PhaseChaitin::Simplify( ) { debug_only( if( lrgs(i)._was_lo ) lo_no_simplify=i; ); double iscore = lrgs(i).score(); double iarea = lrgs(i)._area; + double icost = lrgs(i)._cost; + bool ibound = lrgs(i)._is_bound; // Compare cost/area of i vs cost/area of lo_score. Smaller cost/area // wins. Ties happen because all live ranges in question have spilled // a few times before and the spill-score adds a huge number which // washes out the low order bits. We are choosing the lesser of 2 // evils; in this case pick largest area to spill. + // Ties also happen when live ranges are defined and used only inside + // one block. In which case their area is 0 and score set to max. + // In such case choose bound live range over unbound to free registers + // or with smaller cost to spill. if( iscore < score || - (iscore == score && iarea > area && lrgs(lo_score)._was_spilled2) ) { + (iscore == score && iarea > area && lrgs(lo_score)._was_spilled2) || + (iscore == score && iarea == area && + ( (ibound && !bound) || ibound == bound && (icost < cost) )) ) { lo_score = i; score = iscore; area = iarea; + cost = icost; + bound = ibound; } } LRG *lo_lrg = &lrgs(lo_score); From 9b306d03eed8493eef1becd603167104a331bf43 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 7 Oct 2009 15:38:37 -0700 Subject: [PATCH 031/172] 6885584: A particular class structure causes large allocation spike for jit Reviewed-by: kvn --- hotspot/src/share/vm/opto/phaseX.cpp | 2 +- hotspot/src/share/vm/opto/type.cpp | 34 +++++++---- hotspot/src/share/vm/opto/type.hpp | 6 +- .../test/compiler/6885584/Test6885584.java | 58 +++++++++++++++++++ 4 files changed, 85 insertions(+), 15 deletions(-) create mode 100644 hotspot/test/compiler/6885584/Test6885584.java diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index 02007014ddc..b55e725fbb3 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -1502,7 +1502,7 @@ Node *PhaseCCP::transform_once( Node *n ) { //---------------------------------saturate------------------------------------ const Type* PhaseCCP::saturate(const Type* new_type, const Type* old_type, const Type* limit_type) const { - const Type* wide_type = new_type->widen(old_type); + const Type* wide_type = new_type->widen(old_type, limit_type); if (wide_type != new_type) { // did we widen? // If so, we may have widened beyond the limit type. Clip it back down. new_type = wide_type->filter(limit_type); diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index c21c7c044cd..c22d1e8f6b0 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -1115,7 +1115,7 @@ const Type *TypeInt::xdual() const { //------------------------------widen------------------------------------------ // Only happens for optimistic top-down optimizations. -const Type *TypeInt::widen( const Type *old ) const { +const Type *TypeInt::widen( const Type *old, const Type* limit ) const { // Coming from TOP or such; no widening if( old->base() != Int ) return this; const TypeInt *ot = old->is_int(); @@ -1134,15 +1134,21 @@ const Type *TypeInt::widen( const Type *old ) const { // Now widen new guy. // Check for widening too far if (_widen == WidenMax) { - if (min_jint < _lo && _hi < max_jint) { + int max = max_jint; + int min = min_jint; + if (limit->isa_int()) { + max = limit->is_int()->_hi; + min = limit->is_int()->_lo; + } + if (min < _lo && _hi < max) { // If neither endpoint is extremal yet, push out the endpoint // which is closer to its respective limit. if (_lo >= 0 || // easy common case - (juint)(_lo - min_jint) >= (juint)(max_jint - _hi)) { + (juint)(_lo - min) >= (juint)(max - _hi)) { // Try to widen to an unsigned range type of 31 bits: - return make(_lo, max_jint, WidenMax); + return make(_lo, max, WidenMax); } else { - return make(min_jint, _hi, WidenMax); + return make(min, _hi, WidenMax); } } return TypeInt::INT; @@ -1357,7 +1363,7 @@ const Type *TypeLong::xdual() const { //------------------------------widen------------------------------------------ // Only happens for optimistic top-down optimizations. -const Type *TypeLong::widen( const Type *old ) const { +const Type *TypeLong::widen( const Type *old, const Type* limit ) const { // Coming from TOP or such; no widening if( old->base() != Long ) return this; const TypeLong *ot = old->is_long(); @@ -1376,18 +1382,24 @@ const Type *TypeLong::widen( const Type *old ) const { // Now widen new guy. // Check for widening too far if (_widen == WidenMax) { - if (min_jlong < _lo && _hi < max_jlong) { + jlong max = max_jlong; + jlong min = min_jlong; + if (limit->isa_long()) { + max = limit->is_long()->_hi; + min = limit->is_long()->_lo; + } + if (min < _lo && _hi < max) { // If neither endpoint is extremal yet, push out the endpoint // which is closer to its respective limit. if (_lo >= 0 || // easy common case - (julong)(_lo - min_jlong) >= (julong)(max_jlong - _hi)) { + (julong)(_lo - min) >= (julong)(max - _hi)) { // Try to widen to an unsigned range type of 32/63 bits: - if (_hi < max_juint) + if (max >= max_juint && _hi < max_juint) return make(_lo, max_juint, WidenMax); else - return make(_lo, max_jlong, WidenMax); + return make(_lo, max, WidenMax); } else { - return make(min_jlong, _hi, WidenMax); + return make(min, _hi, WidenMax); } } return TypeLong::LONG; diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp index 4fac900b98c..9b11f9ca595 100644 --- a/hotspot/src/share/vm/opto/type.hpp +++ b/hotspot/src/share/vm/opto/type.hpp @@ -168,7 +168,7 @@ public: // MEET operation; lower in lattice. const Type *meet( const Type *t ) const; // WIDEN: 'widens' for Ints and other range types - virtual const Type *widen( const Type *old ) const { return this; } + virtual const Type *widen( const Type *old, const Type* limit ) const { return this; } // NARROW: complement for widen, used by pessimistic phases virtual const Type *narrow( const Type *old ) const { return this; } @@ -409,7 +409,7 @@ public: virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. - virtual const Type *widen( const Type *t ) const; + virtual const Type *widen( const Type *t, const Type* limit_type ) const; virtual const Type *narrow( const Type *t ) const; // Do not kill _widen bits. virtual const Type *filter( const Type *kills ) const; @@ -465,7 +465,7 @@ public: virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. - virtual const Type *widen( const Type *t ) const; + virtual const Type *widen( const Type *t, const Type* limit_type ) const; virtual const Type *narrow( const Type *t ) const; // Do not kill _widen bits. virtual const Type *filter( const Type *kills ) const; diff --git a/hotspot/test/compiler/6885584/Test6885584.java b/hotspot/test/compiler/6885584/Test6885584.java new file mode 100644 index 00000000000..0dd9f43fd30 --- /dev/null +++ b/hotspot/test/compiler/6885584/Test6885584.java @@ -0,0 +1,58 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +/** + * @test + * @bug 6885584 + * @summary A particular class structure causes large allocation spike for jit + * + * @run main/othervm -Xbatch Test6885584 + */ + + + +public class Test6885584 { + static private int i1; + static private int i2; + static private int i3; + + static int limit = Integer.MAX_VALUE - 8; + + public static void main(String args[]) { + // Run long enough to trigger an OSR + for(int j = 200000; j != 0; j--) { + } + + // This must reference a field + i1 = i2; + + // The resource leak is roughly proportional to this initial value + for(int k = Integer.MAX_VALUE - 1; k != 0; k--) { + // Make sure the body does some work + if(i2 > i3)i1 = k; + if (k <= limit) break; + } + } + +} From a67426faf8a29ffaa1f21c5ae33c74bb2199e5bd Mon Sep 17 00:00:00 2001 From: Antonios Printezis Date: Wed, 7 Oct 2009 19:01:55 -0400 Subject: [PATCH 032/172] 6866190: Remove SIMPLE_STACK code from TaskQueue What the title says. We don't use SIMPLE_STACK any more. Reviewed-by: ysr --- hotspot/src/share/vm/utilities/taskqueue.hpp | 22 -------------------- 1 file changed, 22 deletions(-) diff --git a/hotspot/src/share/vm/utilities/taskqueue.hpp b/hotspot/src/share/vm/utilities/taskqueue.hpp index 6b0076b0d8a..19bdb3245c4 100644 --- a/hotspot/src/share/vm/utilities/taskqueue.hpp +++ b/hotspot/src/share/vm/utilities/taskqueue.hpp @@ -465,19 +465,7 @@ public: #endif }; -#define SIMPLE_STACK 0 - template inline bool GenericTaskQueue::push(E t) { -#if SIMPLE_STACK - uint localBot = _bottom; - if (_bottom < max_elems()) { - _elems[localBot] = t; - _bottom = localBot + 1; - return true; - } else { - return false; - } -#else uint localBot = _bottom; assert((localBot >= 0) && (localBot < N), "_bottom out of range."); idx_t top = _age.top(); @@ -490,18 +478,9 @@ template inline bool GenericTaskQueue::push(E t) { } else { return push_slow(t, dirty_n_elems); } -#endif } template inline bool GenericTaskQueue::pop_local(E& t) { -#if SIMPLE_STACK - uint localBot = _bottom; - assert(localBot > 0, "precondition."); - localBot--; - t = _elems[localBot]; - _bottom = localBot; - return true; -#else uint localBot = _bottom; // This value cannot be N-1. That can only occur as a result of // the assignment to bottom in this method. If it does, this method @@ -529,7 +508,6 @@ template inline bool GenericTaskQueue::pop_local(E& t) { // path. return pop_local_slow(localBot, _age.get()); } -#endif } typedef oop Task; From e31cb363017caf0e51912e980a4b8bd15d3e6b18 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Fri, 9 Oct 2009 09:59:54 +0100 Subject: [PATCH 033/172] 6889552: Sun provider should not require LDAP CertStore to be present Reviewed-by: vinnie, mullan --- .../sun/security/provider/SunEntries.java | 2 +- .../provider/certpath/CertStoreHelper.java | 68 +++++++++++++++++ .../provider/certpath/URICertStore.java | 38 ++++++++-- .../certpath/{ => ldap}/LDAPCertStore.java | 3 +- .../certpath/ldap/LDAPCertStoreHelper.java | 73 +++++++++++++++++++ 5 files changed, 177 insertions(+), 7 deletions(-) create mode 100644 jdk/src/share/classes/sun/security/provider/certpath/CertStoreHelper.java rename jdk/src/share/classes/sun/security/provider/certpath/{ => ldap}/LDAPCertStore.java (99%) create mode 100644 jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreHelper.java diff --git a/jdk/src/share/classes/sun/security/provider/SunEntries.java b/jdk/src/share/classes/sun/security/provider/SunEntries.java index 829ded160d1..817afb8329c 100644 --- a/jdk/src/share/classes/sun/security/provider/SunEntries.java +++ b/jdk/src/share/classes/sun/security/provider/SunEntries.java @@ -210,7 +210,7 @@ final class SunEntries { * CertStores */ map.put("CertStore.LDAP", - "sun.security.provider.certpath.LDAPCertStore"); + "sun.security.provider.certpath.ldap.LDAPCertStore"); map.put("CertStore.LDAP LDAPSchema", "RFC2587"); map.put("CertStore.Collection", "sun.security.provider.certpath.CollectionCertStore"); diff --git a/jdk/src/share/classes/sun/security/provider/certpath/CertStoreHelper.java b/jdk/src/share/classes/sun/security/provider/certpath/CertStoreHelper.java new file mode 100644 index 00000000000..a8f234226dc --- /dev/null +++ b/jdk/src/share/classes/sun/security/provider/certpath/CertStoreHelper.java @@ -0,0 +1,68 @@ +/* + * Copyright 2009 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.security.provider.certpath; + +import java.net.URI; +import java.util.Collection; +import java.security.NoSuchAlgorithmException; +import java.security.InvalidAlgorithmParameterException; +import java.security.cert.CertStore; +import java.security.cert.X509CertSelector; +import java.security.cert.X509CRLSelector; +import javax.security.auth.x500.X500Principal; +import java.io.IOException; + +/** + * Helper used by URICertStore when delegating to another CertStore to + * fetch certs and CRLs. + */ + +public interface CertStoreHelper { + + /** + * Returns a CertStore using the given URI as parameters. + */ + CertStore getCertStore(URI uri) + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException; + + /** + * Wraps an existing X509CertSelector when needing to avoid DN matching + * issues. + */ + X509CertSelector wrap(X509CertSelector selector, + X500Principal certSubject, + String dn) + throws IOException; + + /** + * Wraps an existing X509CRLSelector when needing to avoid DN matching + * issues. + */ + X509CRLSelector wrap(X509CRLSelector selector, + Collection certIssuers, + String dn) + throws IOException; +} diff --git a/jdk/src/share/classes/sun/security/provider/certpath/URICertStore.java b/jdk/src/share/classes/sun/security/provider/certpath/URICertStore.java index 3c0220bbcf9..b042dd78a9b 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/URICertStore.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/URICertStore.java @@ -30,6 +30,8 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.net.URI; import java.net.URLConnection; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.Provider; @@ -120,6 +122,32 @@ class URICertStore extends CertStoreSpi { private CertStore ldapCertStore; private String ldapPath; + /** + * Holder class to lazily load LDAPCertStoreHelper if present. + */ + private static class LDAP { + private static final String CERT_STORE_HELPER = + "sun.security.provider.certpath.ldap.LDAPCertStoreHelper"; + private static final CertStoreHelper helper = + AccessController.doPrivileged( + new PrivilegedAction() { + public CertStoreHelper run() { + try { + Class c = Class.forName(CERT_STORE_HELPER, true, null); + return (CertStoreHelper)c.newInstance(); + } catch (ClassNotFoundException cnf) { + return null; + } catch (InstantiationException e) { + throw new AssertionError(e); + } catch (IllegalAccessException e) { + throw new AssertionError(e); + } + }}); + static CertStoreHelper helper() { + return helper; + } + } + /** * Creates a URICertStore. * @@ -135,9 +163,10 @@ class URICertStore extends CertStoreSpi { this.uri = ((URICertStoreParameters) params).uri; // if ldap URI, use an LDAPCertStore to fetch certs and CRLs if (uri.getScheme().toLowerCase().equals("ldap")) { + if (LDAP.helper() == null) + throw new NoSuchAlgorithmException("LDAP not present"); ldap = true; - ldapCertStore = - LDAPCertStore.getInstance(LDAPCertStore.getParameters(uri)); + ldapCertStore = LDAP.helper().getCertStore(uri); ldapPath = uri.getPath(); // strip off leading '/' if (ldapPath.charAt(0) == '/') { @@ -219,8 +248,7 @@ class URICertStore extends CertStoreSpi { if (ldap) { X509CertSelector xsel = (X509CertSelector) selector; try { - xsel = new LDAPCertStore.LDAPCertSelector - (xsel, xsel.getSubject(), ldapPath); + xsel = LDAP.helper().wrap(xsel, xsel.getSubject(), ldapPath); } catch (IOException ioe) { throw new CertStoreException(ioe); } @@ -340,7 +368,7 @@ class URICertStore extends CertStoreSpi { if (ldap) { X509CRLSelector xsel = (X509CRLSelector) selector; try { - xsel = new LDAPCertStore.LDAPCRLSelector(xsel, null, ldapPath); + xsel = LDAP.helper().wrap(xsel, null, ldapPath); } catch (IOException ioe) { throw new CertStoreException(ioe); } diff --git a/jdk/src/share/classes/sun/security/provider/certpath/LDAPCertStore.java b/jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java similarity index 99% rename from jdk/src/share/classes/sun/security/provider/certpath/LDAPCertStore.java rename to jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java index f7b567bef39..3517245e550 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/LDAPCertStore.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java @@ -23,7 +23,7 @@ * have any questions. */ -package sun.security.provider.certpath; +package sun.security.provider.certpath.ldap; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -46,6 +46,7 @@ import java.security.cert.*; import javax.security.auth.x500.X500Principal; import sun.misc.HexDumpEncoder; +import sun.security.provider.certpath.X509CertificatePair; import sun.security.util.Cache; import sun.security.util.Debug; import sun.security.x509.X500Name; diff --git a/jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreHelper.java b/jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreHelper.java new file mode 100644 index 00000000000..3667022d04d --- /dev/null +++ b/jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreHelper.java @@ -0,0 +1,73 @@ +/* + * Copyright 2009 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.security.provider.certpath.ldap; + +import java.net.URI; +import java.util.Collection; +import java.security.NoSuchAlgorithmException; +import java.security.InvalidAlgorithmParameterException; +import java.security.cert.CertStore; +import java.security.cert.X509CertSelector; +import java.security.cert.X509CRLSelector; +import javax.security.auth.x500.X500Principal; +import java.io.IOException; + +import sun.security.provider.certpath.CertStoreHelper; + +/** + * LDAP implementation of CertStoreHelper. + */ + +public class LDAPCertStoreHelper + implements CertStoreHelper +{ + public LDAPCertStoreHelper() { } + + @Override + public CertStore getCertStore(URI uri) + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException + { + return LDAPCertStore.getInstance(LDAPCertStore.getParameters(uri)); + } + + @Override + public X509CertSelector wrap(X509CertSelector selector, + X500Principal certSubject, + String ldapDN) + throws IOException + { + return new LDAPCertStore.LDAPCertSelector(selector, certSubject, ldapDN); + } + + @Override + public X509CRLSelector wrap(X509CRLSelector selector, + Collection certIssuers, + String ldapDN) + throws IOException + { + return new LDAPCertStore.LDAPCRLSelector(selector, certIssuers, ldapDN); + } +} From c44758929fcfa1a558bd1944bbe4c0ec63fee438 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Fri, 9 Oct 2009 10:06:58 +0100 Subject: [PATCH 034/172] 6888552: Allow JNDI to be used when java.applet is not present Reviewed-by: vinnie --- .../sun/naming/internal/ResourceManager.java | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/com/sun/naming/internal/ResourceManager.java b/jdk/src/share/classes/com/sun/naming/internal/ResourceManager.java index d02faa63cba..ec46bfdf2c0 100644 --- a/jdk/src/share/classes/com/sun/naming/internal/ResourceManager.java +++ b/jdk/src/share/classes/com/sun/naming/internal/ResourceManager.java @@ -25,11 +25,12 @@ package com.sun.naming.internal; -import java.applet.Applet; import java.io.InputStream; import java.io.IOException; import java.net.URL; import java.lang.ref.WeakReference; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; @@ -112,6 +113,52 @@ public final class ResourceManager { private static final WeakHashMap urlFactoryCache = new WeakHashMap(11); private static final WeakReference NO_FACTORY = new WeakReference(null); + /** + * A class to allow JNDI properties be specified as applet parameters + * without creating a static dependency on java.applet. + */ + private static class AppletParameter { + private static final Class clazz = getClass("java.applet.Applet"); + private static final Method getMethod = + getMethod(clazz, "getParameter", String.class); + private static Class getClass(String name) { + try { + return Class.forName(name, true, null); + } catch (ClassNotFoundException e) { + return null; + } + } + private static Method getMethod(Class clazz, + String name, + Class... paramTypes) + { + if (clazz != null) { + try { + return clazz.getMethod(name, paramTypes); + } catch (NoSuchMethodException e) { + throw new AssertionError(e); + } + } else { + return null; + } + } + + /** + * Returns the value of the applet's named parameter. + */ + static Object get(Object applet, String name) { + // if clazz is null then applet cannot be an Applet. + if (clazz == null || !clazz.isInstance(applet)) + throw new ClassCastException(applet.getClass().getName()); + try { + return getMethod.invoke(applet, name); + } catch (InvocationTargetException e) { + throw new AssertionError(e); + } catch (IllegalAccessException iae) { + throw new AssertionError(iae); + } + } + } // There should be no instances of this class. private ResourceManager() { @@ -143,7 +190,7 @@ public final class ResourceManager { if (env == null) { env = new Hashtable(11); } - Applet applet = (Applet)env.get(Context.APPLET); + Object applet = env.get(Context.APPLET); // Merge property values from env param, applet params, and system // properties. The first value wins: there's no concatenation of @@ -157,7 +204,7 @@ public final class ResourceManager { Object val = env.get(props[i]); if (val == null) { if (applet != null) { - val = applet.getParameter(props[i]); + val = AppletParameter.get(applet, props[i]); } if (val == null) { // Read system property. From eca779ecad50de07607a3ea7e5a0feb66fdacac8 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Fri, 9 Oct 2009 16:11:11 -0700 Subject: [PATCH 035/172] 6797535: Add shared two argument static equals method to the platform Reviewed-by: sherman --- jdk/make/java/java/FILES_java.gmk | 1 + jdk/src/share/classes/java/util/Objects.java | 110 ++++++++++++++++++ .../java/util/Objects/BasicObjectsTest.java | 105 +++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 jdk/src/share/classes/java/util/Objects.java create mode 100644 jdk/test/java/util/Objects/BasicObjectsTest.java diff --git a/jdk/make/java/java/FILES_java.gmk b/jdk/make/java/java/FILES_java.gmk index 2ad599cbe23..d9b7e153d72 100644 --- a/jdk/make/java/java/FILES_java.gmk +++ b/jdk/make/java/java/FILES_java.gmk @@ -258,6 +258,7 @@ JAVA_JAVA_java = \ java/util/ServiceConfigurationError.java \ java/util/Timer.java \ java/util/TimerTask.java \ + java/util/Objects.java \ java/util/UUID.java \ java/util/concurrent/AbstractExecutorService.java \ java/util/concurrent/ArrayBlockingQueue.java \ diff --git a/jdk/src/share/classes/java/util/Objects.java b/jdk/src/share/classes/java/util/Objects.java new file mode 100644 index 00000000000..9d05c314d89 --- /dev/null +++ b/jdk/src/share/classes/java/util/Objects.java @@ -0,0 +1,110 @@ +/* + * Copyright 2009 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.util; + +/** + * This class consists of {@code static} utility methods for operating + * on objects. These utilities include {@code null}-safe or {@code + * null}-tolerant methods for computing the hash code of an object, + * returning a string for an object, and comparing two objects. + * + * @since 1.7 + */ +public class Objects { + private Objects() { + throw new AssertionError("No java.util.Objects instances for you!"); + } + + /** + * Returns {@code true} if the arguments are equal to each other + * and {@code false} otherwise. + * Consequently, if both arguments are {@code null}, {@code true} + * is returned and if exactly one argument is {@code null}, {@code + * false} is returned. Otherwise, equality is determined by using + * the {@link Object#equals equals} method of the first + * argument. + * + * @param a an object + * @param b an object to be compared with {@code a} for equality + * @return {@code true} if the arguments are equal to each other + * and {@code false} otherwise + * @see Object#equals(Object) + */ + public static boolean equals(Object a, Object b) { + return (a == b) || (a != null && a.equals(b)); + } + + /** + * Returns the hash code of a non-{@code null} argument and 0 for + * a {@code null} argument. + * + * @param o an object + * @return the hash code of a non-{@code null} argument and 0 for + * a {@code null} argument + * @see Object#hashCode + */ + public static int hashCode(Object o) { + return o != null ? o.hashCode() : 0; + } + + /** + * Returns the result of calling {@code toString} for a non-{@code + * null} argument and {@code "null"} for a {@code null} argument. + * + * @param o an object + * @return the result of calling {@code toString} for a non-{@code + * null} argument and {@code "null"} for a {@code null} argument + * @see Object#toString + * @see String#valueOf(Object) + */ + public static String toString(Object o) { + return String.valueOf(o); + } + + /** + * Returns 0 if the arguments are identical and {@code + * c.compare(a, b)} otherwise. + * Consequently, if both arguments are {@code null} 0 + * is returned. + * + *

Note that if one of the arguments is {@code null}, a {@code + * NullPointerException} may or may not be thrown depending on + * what ordering policy, if any, the {@link Comparator Comparator} + * chooses to have for {@code null} values. + * + * @param the type of the objects being compared + * @param a an object + * @param b an object to be compared with {@code a} + * @param c the {@code Comparator} to compare the first two arguments + * @return 0 if the arguments are identical and {@code + * c.compare(a, b)} otherwise. + * @see Comparable + * @see Comparator + */ + public static int compare(T a, T b, Comparator c) { + return (a == b) ? 0 : c.compare(a, b); + } +} diff --git a/jdk/test/java/util/Objects/BasicObjectsTest.java b/jdk/test/java/util/Objects/BasicObjectsTest.java new file mode 100644 index 00000000000..be45b2c92ed --- /dev/null +++ b/jdk/test/java/util/Objects/BasicObjectsTest.java @@ -0,0 +1,105 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6797535 + * @summary Basic tests for methods in java.util.Objects + * @author Joseph D. Darcy + */ + +import java.util.*; + +public class BasicObjectsTest { + public static void main(String... args) { + int errors = 0; + errors += testEquals(); + errors += testHashCode(); + errors += testToString(); + errors += testCompare(); + if (errors > 0 ) + throw new RuntimeException(); + } + + private static int testEquals() { + int errors = 0; + Object[] values = {null, "42", 42}; + for(int i = 0; i < values.length; i++) + for(int j = 0; j < values.length; j++) { + boolean expected = (i == j); + Object a = values[i]; + Object b = values[j]; + boolean result = Objects.equals(a, b); + if (result != expected) { + errors++; + System.err.printf("When equating %s to %s, got %b instead of %b%n.", + a, b, result, expected); + } + } + return errors; + } + + private static int testHashCode() { + int errors = 0; + errors += (Objects.hashCode(null) == 0 ) ? 0 : 1; + String s = "42"; + errors += (Objects.hashCode(s) == s.hashCode() ) ? 0 : 1; + return errors; + } + + private static int testToString() { + int errors = 0; + errors += ("null".equals(Objects.toString(null)) ) ? 0 : 1; + String s = "Some string"; + errors += (s.equals(Objects.toString(s)) ) ? 0 : 1; + return errors; + } + + private static int testCompare() { + int errors = 0; + String[] values = {"e. e. cummings", "zzz"}; + String[] VALUES = {"E. E. Cummings", "ZZZ"}; + errors += compareTest(null, null, 0); + for(int i = 0; i < values.length; i++) { + String a = values[i]; + errors += compareTest(a, a, 0); + for(int j = 0; j < VALUES.length; j++) { + int expected = Integer.compare(i, j); + String b = VALUES[j]; + errors += compareTest(a, b, expected); + } + } + return errors; + } + + private static int compareTest(String a, String b, int expected) { + int errors = 0; + int result = Objects.compare(a, b, String.CASE_INSENSITIVE_ORDER); + if (Integer.signum(result) != Integer.signum(expected)) { + errors++; + System.err.printf("When comparing %s to %s, got %d instead of %d%n.", + a, b, result, expected); + } + return errors; + } +} From 7628a594141102e8ed200ea483af496b024bdf9b Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Mon, 12 Oct 2009 19:07:43 +0400 Subject: [PATCH 036/172] 6796915: Deadlock in XAWT when switching virtual desktops Reviewed-by: art, anthony --- .../sun/awt/X11/XDropTargetRegistry.java | 88 +++++++++---------- .../classes/sun/awt/X11/XWindowPeer.java | 52 +++++++---- 2 files changed, 78 insertions(+), 62 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java index 1678d92a6bd..84f67fb01b2 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java @@ -534,71 +534,71 @@ final class XDropTargetRegistry { return entry.getSite(x, y); } + /* + * Note: this method should be called under AWT lock. + */ public void registerDropSite(long window) { + assert XToolkit.isAWTLockHeldByCurrentThread(); + if (window == 0) { throw new IllegalArgumentException(); } XDropTargetEventProcessor.activate(); - XToolkit.awtLock(); - try { - long toplevel = getToplevelWindow(window); + long toplevel = getToplevelWindow(window); - /* - * No window with WM_STATE property is found. - * Since the window can be a plugin window reparented to the browser - * toplevel, we cannot determine which window will eventually have - * WM_STATE property set. So we schedule a timer callback that will - * periodically attempt to find an ancestor with WM_STATE and - * register the drop site appropriately. - */ - if (toplevel == 0) { - addDelayedRegistrationEntry(window); - return; + /* + * No window with WM_STATE property is found. + * Since the window can be a plugin window reparented to the browser + * toplevel, we cannot determine which window will eventually have + * WM_STATE property set. So we schedule a timer callback that will + * periodically attempt to find an ancestor with WM_STATE and + * register the drop site appropriately. + */ + if (toplevel == 0) { + addDelayedRegistrationEntry(window); + return; + } + + if (toplevel == window) { + Iterator dropTargetProtocols = + XDragAndDropProtocols.getDropTargetProtocols(); + + while (dropTargetProtocols.hasNext()) { + XDropTargetProtocol dropTargetProtocol = + (XDropTargetProtocol)dropTargetProtocols.next(); + dropTargetProtocol.registerDropTarget(toplevel); } - - if (toplevel == window) { - Iterator dropTargetProtocols = - XDragAndDropProtocols.getDropTargetProtocols(); - - while (dropTargetProtocols.hasNext()) { - XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); - dropTargetProtocol.registerDropTarget(toplevel); - } - } else { - registerEmbeddedDropSite(toplevel, window); - } - } finally { - XToolkit.awtUnlock(); + } else { + registerEmbeddedDropSite(toplevel, window); } } + /* + * Note: this method should be called under AWT lock. + */ public void unregisterDropSite(long window) { + assert XToolkit.isAWTLockHeldByCurrentThread(); + if (window == 0) { throw new IllegalArgumentException(); } - XToolkit.awtLock(); - try { - long toplevel = getToplevelWindow(window); + long toplevel = getToplevelWindow(window); - if (toplevel == window) { - Iterator dropProtocols = - XDragAndDropProtocols.getDropTargetProtocols(); + if (toplevel == window) { + Iterator dropProtocols = + XDragAndDropProtocols.getDropTargetProtocols(); - removeDelayedRegistrationEntry(window); + removeDelayedRegistrationEntry(window); - while (dropProtocols.hasNext()) { - XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next(); - dropProtocol.unregisterDropTarget(window); - } - } else { - unregisterEmbeddedDropSite(toplevel, window); + while (dropProtocols.hasNext()) { + XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next(); + dropProtocol.unregisterDropTarget(window); } - } finally { - XToolkit.awtUnlock(); + } else { + unregisterEmbeddedDropSite(toplevel, window); } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java index b1646413b79..076526fd653 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java @@ -1757,25 +1757,36 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, } } + // should be synchronized on awtLock private int dropTargetCount = 0; - public synchronized void addDropTarget() { - if (dropTargetCount == 0) { - long window = getWindow(); - if (window != 0) { - XDropTargetRegistry.getRegistry().registerDropSite(window); + public void addDropTarget() { + XToolkit.awtLock(); + try { + if (dropTargetCount == 0) { + long window = getWindow(); + if (window != 0) { + XDropTargetRegistry.getRegistry().registerDropSite(window); + } } + dropTargetCount++; + } finally { + XToolkit.awtUnlock(); } - dropTargetCount++; } - public synchronized void removeDropTarget() { - dropTargetCount--; - if (dropTargetCount == 0) { - long window = getWindow(); - if (window != 0) { - XDropTargetRegistry.getRegistry().unregisterDropSite(window); + public void removeDropTarget() { + XToolkit.awtLock(); + try { + dropTargetCount--; + if (dropTargetCount == 0) { + long window = getWindow(); + if (window != 0) { + XDropTargetRegistry.getRegistry().unregisterDropSite(window); + } } + } finally { + XToolkit.awtUnlock(); } } void addRootPropertyEventDispatcher() { @@ -1838,13 +1849,18 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, } } - protected synchronized void updateDropTarget() { - if (dropTargetCount > 0) { - long window = getWindow(); - if (window != 0) { - XDropTargetRegistry.getRegistry().unregisterDropSite(window); - XDropTargetRegistry.getRegistry().registerDropSite(window); + protected void updateDropTarget() { + XToolkit.awtLock(); + try { + if (dropTargetCount > 0) { + long window = getWindow(); + if (window != 0) { + XDropTargetRegistry.getRegistry().unregisterDropSite(window); + XDropTargetRegistry.getRegistry().registerDropSite(window); + } } + } finally { + XToolkit.awtUnlock(); } } From 5473f394c6cb3a13505f03957a32e392b0407846 Mon Sep 17 00:00:00 2001 From: Gary Benson Date: Tue, 13 Oct 2009 12:04:21 -0700 Subject: [PATCH 037/172] 6890308: integrate zero assembler hotspot changes Reviewed-by: never --- hotspot/make/Makefile | 36 +- hotspot/make/defs.make | 6 +- hotspot/make/linux/Makefile | 48 +- hotspot/make/linux/makefiles/buildtree.make | 23 +- hotspot/make/linux/makefiles/defs.make | 37 +- hotspot/make/linux/makefiles/gcc.make | 4 + hotspot/make/linux/makefiles/sa.make | 4 +- hotspot/make/linux/makefiles/saproc.make | 4 +- hotspot/make/linux/makefiles/top.make | 1 + hotspot/make/linux/makefiles/vm.make | 15 +- hotspot/make/linux/makefiles/zero.make | 32 + hotspot/make/linux/makefiles/zeroshark.make | 43 + hotspot/make/linux/platform_zero.in | 17 + hotspot/src/cpu/zero/vm/assembler_zero.cpp | 77 ++ hotspot/src/cpu/zero/vm/assembler_zero.hpp | 64 ++ .../src/cpu/zero/vm/assembler_zero.inline.hpp | 26 + .../cpu/zero/vm/bytecodeInterpreter_zero.cpp | 54 + .../cpu/zero/vm/bytecodeInterpreter_zero.hpp | 148 +++ .../vm/bytecodeInterpreter_zero.inline.hpp | 301 ++++++ hotspot/src/cpu/zero/vm/bytecodes_zero.cpp | 31 + hotspot/src/cpu/zero/vm/bytecodes_zero.hpp | 26 + hotspot/src/cpu/zero/vm/bytes_zero.hpp | 164 +++ hotspot/src/cpu/zero/vm/codeBuffer_zero.hpp | 27 + hotspot/src/cpu/zero/vm/copy_zero.hpp | 178 ++++ .../zero/vm/cppInterpreterGenerator_zero.hpp | 37 + .../src/cpu/zero/vm/cppInterpreter_zero.cpp | 946 ++++++++++++++++++ .../src/cpu/zero/vm/cppInterpreter_zero.hpp | 43 + hotspot/src/cpu/zero/vm/debug_zero.cpp | 31 + hotspot/src/cpu/zero/vm/depChecker_zero.cpp | 26 + hotspot/src/cpu/zero/vm/depChecker_zero.hpp | 26 + hotspot/src/cpu/zero/vm/disassembler_zero.cpp | 26 + hotspot/src/cpu/zero/vm/disassembler_zero.hpp | 35 + hotspot/src/cpu/zero/vm/dump_zero.cpp | 36 + hotspot/src/cpu/zero/vm/entryFrame_zero.hpp | 65 ++ hotspot/src/cpu/zero/vm/entry_zero.hpp | 64 ++ .../src/cpu/zero/vm/fakeStubFrame_zero.hpp | 53 + hotspot/src/cpu/zero/vm/frame_zero.cpp | 414 ++++++++ hotspot/src/cpu/zero/vm/frame_zero.hpp | 77 ++ hotspot/src/cpu/zero/vm/frame_zero.inline.hpp | 151 +++ .../cpu/zero/vm/globalDefinitions_zero.hpp | 26 + hotspot/src/cpu/zero/vm/globals_zero.hpp | 55 + hotspot/src/cpu/zero/vm/icBuffer_zero.cpp | 49 + hotspot/src/cpu/zero/vm/icache_zero.cpp | 32 + hotspot/src/cpu/zero/vm/icache_zero.hpp | 36 + hotspot/src/cpu/zero/vm/interp_masm_zero.cpp | 26 + hotspot/src/cpu/zero/vm/interp_masm_zero.hpp | 38 + .../src/cpu/zero/vm/interpreterFrame_zero.hpp | 75 ++ .../cpu/zero/vm/interpreterGenerator_zero.hpp | 37 + .../src/cpu/zero/vm/interpreterRT_zero.cpp | 162 +++ .../src/cpu/zero/vm/interpreterRT_zero.hpp | 127 +++ hotspot/src/cpu/zero/vm/interpreter_zero.cpp | 70 ++ hotspot/src/cpu/zero/vm/interpreter_zero.hpp | 61 ++ .../src/cpu/zero/vm/javaFrameAnchor_zero.hpp | 72 ++ .../src/cpu/zero/vm/jniFastGetField_zero.cpp | 59 ++ hotspot/src/cpu/zero/vm/jniTypes_zero.hpp | 108 ++ hotspot/src/cpu/zero/vm/jni_zero.h | 38 + .../src/cpu/zero/vm/methodHandles_zero.cpp | 26 + hotspot/src/cpu/zero/vm/nativeInst_zero.cpp | 50 + hotspot/src/cpu/zero/vm/nativeInst_zero.hpp | 185 ++++ hotspot/src/cpu/zero/vm/registerMap_zero.hpp | 39 + .../cpu/zero/vm/register_definitions_zero.cpp | 26 + hotspot/src/cpu/zero/vm/register_zero.cpp | 39 + hotspot/src/cpu/zero/vm/register_zero.hpp | 110 ++ hotspot/src/cpu/zero/vm/relocInfo_zero.cpp | 74 ++ hotspot/src/cpu/zero/vm/relocInfo_zero.hpp | 32 + .../src/cpu/zero/vm/sharedRuntime_zero.cpp | 108 ++ hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp | 79 ++ hotspot/src/cpu/zero/vm/stack_zero.hpp | 197 ++++ .../src/cpu/zero/vm/stubGenerator_zero.cpp | 251 +++++ hotspot/src/cpu/zero/vm/stubRoutines_zero.cpp | 31 + hotspot/src/cpu/zero/vm/stubRoutines_zero.hpp | 51 + .../vm/templateInterpreterGenerator_zero.hpp | 26 + .../cpu/zero/vm/templateInterpreter_zero.cpp | 26 + .../cpu/zero/vm/templateInterpreter_zero.hpp | 26 + .../src/cpu/zero/vm/templateTable_zero.cpp | 26 + .../src/cpu/zero/vm/templateTable_zero.hpp | 26 + hotspot/src/cpu/zero/vm/vmStructs_zero.hpp | 52 + hotspot/src/cpu/zero/vm/vm_version_zero.cpp | 26 + hotspot/src/cpu/zero/vm/vm_version_zero.hpp | 31 + hotspot/src/cpu/zero/vm/vmreg_zero.cpp | 62 ++ hotspot/src/cpu/zero/vm/vmreg_zero.hpp | 29 + hotspot/src/cpu/zero/vm/vmreg_zero.inline.hpp | 32 + hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp | 43 + hotspot/src/os/linux/vm/os_linux.cpp | 33 +- .../linux_zero/vm/assembler_linux_zero.cpp | 26 + .../vm/atomic_linux_zero.inline.hpp | 293 ++++++ .../linux_zero/vm/bytes_linux_zero.inline.hpp | 40 + .../linux_zero/vm/globals_linux_zero.hpp | 45 + .../vm/orderAccess_linux_zero.inline.hpp | 167 ++++ .../os_cpu/linux_zero/vm/os_linux_zero.cpp | 456 +++++++++ .../os_cpu/linux_zero/vm/os_linux_zero.hpp | 45 + .../vm/prefetch_linux_zero.inline.hpp | 30 + .../linux_zero/vm/threadLS_linux_zero.cpp | 39 + .../linux_zero/vm/threadLS_linux_zero.hpp | 30 + .../linux_zero/vm/thread_linux_zero.cpp | 26 + .../linux_zero/vm/thread_linux_zero.hpp | 104 ++ .../linux_zero/vm/vmStructs_linux_zero.hpp | 45 + .../linux_zero/vm/vm_version_linux_zero.cpp | 26 + hotspot/src/share/vm/includeDB_zero | 55 + .../vm/interpreter/bytecodeInterpreter.cpp | 4 +- .../src/share/vm/interpreter/oopMapCache.cpp | 2 +- hotspot/src/share/vm/runtime/arguments.cpp | 2 + hotspot/src/share/vm/runtime/globals.hpp | 1 - hotspot/src/share/vm/runtime/jniHandles.hpp | 4 + hotspot/src/share/vm/runtime/mutex.hpp | 10 +- hotspot/src/share/vm/runtime/signature.hpp | 11 +- hotspot/src/share/vm/runtime/vm_version.cpp | 14 +- hotspot/src/share/vm/utilities/vmError.cpp | 35 + 108 files changed, 7657 insertions(+), 56 deletions(-) create mode 100644 hotspot/make/linux/makefiles/zero.make create mode 100644 hotspot/make/linux/makefiles/zeroshark.make create mode 100644 hotspot/make/linux/platform_zero.in create mode 100644 hotspot/src/cpu/zero/vm/assembler_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/assembler_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/assembler_zero.inline.hpp create mode 100644 hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp create mode 100644 hotspot/src/cpu/zero/vm/bytecodes_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/bytecodes_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/bytes_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/codeBuffer_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/copy_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/debug_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/depChecker_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/depChecker_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/disassembler_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/disassembler_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/dump_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/entryFrame_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/entry_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/fakeStubFrame_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/frame_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/frame_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/frame_zero.inline.hpp create mode 100644 hotspot/src/cpu/zero/vm/globalDefinitions_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/globals_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/icBuffer_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/icache_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/icache_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/interp_masm_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/interp_masm_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/interpreterGenerator_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/interpreterRT_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/interpreter_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/interpreter_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/jniFastGetField_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/jniTypes_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/jni_zero.h create mode 100644 hotspot/src/cpu/zero/vm/methodHandles_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/nativeInst_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/nativeInst_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/registerMap_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/register_definitions_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/register_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/register_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/relocInfo_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/relocInfo_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/stack_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/stubRoutines_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/stubRoutines_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/templateInterpreterGenerator_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/templateInterpreter_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/templateInterpreter_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/templateTable_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/templateTable_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/vmStructs_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/vm_version_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/vm_version_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/vmreg_zero.cpp create mode 100644 hotspot/src/cpu/zero/vm/vmreg_zero.hpp create mode 100644 hotspot/src/cpu/zero/vm/vmreg_zero.inline.hpp create mode 100644 hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/bytes_linux_zero.inline.hpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/prefetch_linux_zero.inline.hpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp create mode 100644 hotspot/src/os_cpu/linux_zero/vm/vm_version_linux_zero.cpp create mode 100644 hotspot/src/share/vm/includeDB_zero diff --git a/hotspot/make/Makefile b/hotspot/make/Makefile index bd2744180ce..6186b3fead8 100644 --- a/hotspot/make/Makefile +++ b/hotspot/make/Makefile @@ -84,6 +84,7 @@ endif C1_VM_TARGETS=product1 fastdebug1 optimized1 jvmg1 C2_VM_TARGETS=product fastdebug optimized jvmg KERNEL_VM_TARGETS=productkernel fastdebugkernel optimizedkernel jvmgkernel +ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero # JDK directory list JDK_DIRS=bin include jre lib demo @@ -94,6 +95,12 @@ all_fastdebug: fastdebug fastdebug1 fastdebugkernel docs export_fastdebug all_debug: jvmg jvmg1 jvmgkernel docs export_debug all_optimized: optimized optimized1 optimizedkernel docs export_optimized +allzero: all_productzero all_fastdebugzero +all_productzero: productzero docs export_product +all_fastdebugzero: fastdebugzero docs export_fastdebug +all_debugzero: jvmgzero docs export_debug +all_optimizedzero: optimizedzero docs export_optimized + # Do everything world: all create_jdk @@ -120,6 +127,10 @@ $(KERNEL_VM_TARGETS): $(CD) $(GAMMADIR)/make; \ $(MAKE) VM_TARGET=$@ generic_buildkernel $(ALT_OUT) +$(ZERO_VM_TARGETS): + $(CD) $(GAMMADIR)/make; \ + $(MAKE) VM_TARGET=$@ generic_buildzero $(ALT_OUT) + # Build compiler1 (client) rule, different for platforms generic_build1: $(MKDIR) -p $(OUTPUTDIR) @@ -180,6 +191,12 @@ else @$(ECHO) "No kernel ($(VM_TARGET)) for OS_NAME=$(OSNAME)" endif +generic_buildzero: + $(MKDIR) -p $(OUTPUTDIR) + $(CD) $(OUTPUTDIR); \ + $(MAKE) -f $(ABS_OS_MAKEFILE) \ + $(MAKE_ARGS) $(VM_TARGET) + # Export file rule generic_export: $(EXPORT_LIST) export_product: @@ -210,11 +227,17 @@ DOCS_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_docs C1_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1 C2_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2 KERNEL_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_kernel +ZERO_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_zero C1_DIR=$(C1_BASE_DIR)/$(VM_SUBDIR) C2_DIR=$(C2_BASE_DIR)/$(VM_SUBDIR) KERNEL_DIR=$(KERNEL_BASE_DIR)/$(VM_SUBDIR) +ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR) # Misc files and generated files need to come from C1 or C2 area +ifeq ($(ZERO_BUILD), true) + MISC_DIR=$(ZERO_DIR) + GEN_DIR=$(ZERO_BASE_DIR)/generated +else ifeq ($(ARCH_DATA_MODEL), 32) MISC_DIR=$(C1_DIR) GEN_DIR=$(C1_BASE_DIR)/generated @@ -222,6 +245,7 @@ else MISC_DIR=$(C2_DIR) GEN_DIR=$(C2_BASE_DIR)/generated endif +endif # Bin files (windows) ifeq ($(OSNAME),windows) @@ -265,6 +289,12 @@ endif # Shared Library ifneq ($(OSNAME),windows) + ifeq ($(ZERO_BUILD), true) +$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(ZERO_DIR)/%.so + $(install-file) +$(EXPORT_SERVER_DIR)/%.so: $(ZERO_DIR)/%.so + $(install-file) + else $(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(C2_DIR)/%.so $(install-file) $(EXPORT_CLIENT_DIR)/%.so: $(C1_DIR)/%.so @@ -275,6 +305,7 @@ $(EXPORT_SERVER_DIR)/%.so: $(C2_DIR)/%.so $(install-file) $(EXPORT_SERVER_DIR)/64/%.so: $(C2_DIR)/%.so $(install-file) + endif endif # Jar file (sa-jdi.jar) @@ -313,6 +344,7 @@ clean_build: $(RM) -r $(C1_DIR) $(RM) -r $(C2_DIR) $(RM) -r $(KERNEL_DIR) + $(RM) -r $(ZERO_DIR) clean_export: $(RM) -r $(EXPORT_PATH) clean_jdk: @@ -335,8 +367,10 @@ $(JDK_IMAGE_DIR)/jre/lib/rt.jar: ($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xf -) test_jdk: - ifeq ($(ARCH_DATA_MODEL), 32) + ifneq ($(ZERO_BUILD), true) + ifeq ($(ARCH_DATA_MODEL), 32) $(JDK_IMAGE_DIR)/bin/java -client -version + endif endif $(JDK_IMAGE_DIR)/bin/java -server -version diff --git a/hotspot/make/defs.make b/hotspot/make/defs.make index 5e94726b3f3..83ddd1a9678 100644 --- a/hotspot/make/defs.make +++ b/hotspot/make/defs.make @@ -192,13 +192,14 @@ ifneq ($(OSNAME),windows) # Use uname output for SRCARCH, but deal with platform differences. If ARCH # is not explicitly listed below, it is treated as x86. - SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64,$(ARCH))) + SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 zero,$(ARCH))) ARCH/ = x86 ARCH/sparc = sparc ARCH/sparc64= sparc ARCH/ia64 = ia64 ARCH/amd64 = x86 ARCH/x86_64 = x86 + ARCH/zero = zero # BUILDARCH is usually the same as SRCARCH, except for sparcv9 BUILDARCH = $(SRCARCH) @@ -222,8 +223,9 @@ ifneq ($(OSNAME),windows) LIBARCH/sparc = sparc LIBARCH/sparcv9 = sparcv9 LIBARCH/ia64 = ia64 + LIBARCH/zero = $(ZERO_LIBARCH) - LP64_ARCH = sparcv9 amd64 ia64 + LP64_ARCH = sparcv9 amd64 ia64 zero endif # Required make macro settings for all platforms diff --git a/hotspot/make/linux/Makefile b/hotspot/make/linux/Makefile index 21f2b3d7f5a..8c86ed287fe 100644 --- a/hotspot/make/linux/Makefile +++ b/hotspot/make/linux/Makefile @@ -132,6 +132,9 @@ ifeq ($(OSNAME),solaris) endif +# BUILDARCH is set to "zero" for Zero builds. VARIANTARCH +# is used to give the build directories meaningful names. +VARIANTARCH = $(subst i386,i486,$(ZERO_LIBARCH)) # There is a (semi-) regular correspondence between make targets and actions: # @@ -158,6 +161,13 @@ endif # profiledcore core __core/profiled # productcore core __core/product # +# debugzero zero __zero/debug +# fastdebugzero zero __zero/fastdebug +# jvmgzero zero __zero/jvmg +# optimizedzero zero __zero/optimized +# profiledzero zero __zero/profiled +# productzero zero __zero/product +# # What you get with each target: # # debug* - "thin" libjvm_g - debug info linked into the gamma_g launcher @@ -171,16 +181,22 @@ endif # in the build.sh script: TARGETS = debug jvmg fastdebug optimized profiled product -SUBDIR_DOCS = $(OSNAME)_$(BUILDARCH)_docs +ifeq ($(ZERO_BUILD), true) + SUBDIR_DOCS = $(OSNAME)_$(VARIANTARCH)_docs +else + SUBDIR_DOCS = $(OSNAME)_$(BUILDARCH)_docs +endif SUBDIRS_C1 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler1/,$(TARGETS)) SUBDIRS_C2 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler2/,$(TARGETS)) SUBDIRS_TIERED = $(addprefix $(OSNAME)_$(BUILDARCH)_tiered/,$(TARGETS)) SUBDIRS_CORE = $(addprefix $(OSNAME)_$(BUILDARCH)_core/,$(TARGETS)) +SUBDIRS_ZERO = $(addprefix $(OSNAME)_$(VARIANTARCH)_zero/,$(TARGETS)) TARGETS_C2 = $(TARGETS) TARGETS_C1 = $(addsuffix 1,$(TARGETS)) TARGETS_TIERED = $(addsuffix tiered,$(TARGETS)) TARGETS_CORE = $(addsuffix core,$(TARGETS)) +TARGETS_ZERO = $(addsuffix zero,$(TARGETS)) BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) ARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) @@ -196,6 +212,7 @@ all: @echo " $(TARGETS_C2)" @echo " $(TARGETS_C1)" @echo " $(TARGETS_CORE)" + @echo " $(TARGETS_ZERO)" checks: check_os_version check_j2se_version @@ -245,6 +262,13 @@ $(SUBDIRS_CORE): $(BUILDTREE_MAKE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks $(BUILDTREE) VARIANT=core +$(SUBDIRS_ZERO): $(BUILDTREE_MAKE) platform_zero + $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks + $(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH) + +platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in + $(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@ + # Define INSTALL=y at command line to automatically copy JVM into JAVA_HOME $(TARGETS_C2): $(SUBDIRS_C2) @@ -275,10 +299,18 @@ ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install endif +$(TARGETS_ZERO): $(SUBDIRS_ZERO) + cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) + cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && ./test_gamma +ifdef INSTALL + cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) install +endif + # Just build the tree, and nothing else: tree: $(SUBDIRS_C2) tree1: $(SUBDIRS_C1) treecore: $(SUBDIRS_CORE) +treezero: $(SUBDIRS_ZERO) # Doc target. This is the same for all build options. # Hence create a docs directory beside ...$(ARCH)_[...] @@ -293,20 +325,22 @@ compiler1: jvmg1 product1 core: jvmgcore productcore +zero: jvmgzero productzero + clean_docs: rm -rf $(SUBDIR_DOCS) -clean_compiler1 clean_compiler2 clean_core: +clean_compiler1 clean_compiler2 clean_core clean_zero: rm -rf $(OSNAME)_$(BUILDARCH)_$(subst clean_,,$@) -clean: clean_compiler2 clean_compiler1 clean_core clean_docs +clean: clean_compiler2 clean_compiler1 clean_core clean_zero clean_docs include $(GAMMADIR)/make/$(OSNAME)/makefiles/cscope.make #------------------------------------------------------------------------------- -.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) -.PHONY: tree tree1 treecore -.PHONY: all compiler1 compiler2 core -.PHONY: clean clean_compiler1 clean_compiler2 clean_core docs clean_docs +.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO) +.PHONY: tree tree1 treecore treezero +.PHONY: all compiler1 compiler2 core zero +.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero docs clean_docs .PHONY: checks check_os_version check_j2se_version diff --git a/hotspot/make/linux/makefiles/buildtree.make b/hotspot/make/linux/makefiles/buildtree.make index 005ef37cd42..0e2b55d2907 100644 --- a/hotspot/make/linux/makefiles/buildtree.make +++ b/hotspot/make/linux/makefiles/buildtree.make @@ -63,20 +63,30 @@ QUIETLY$(MAKE_VERBOSE) = @ # For now, until the compiler is less wobbly: TESTFLAGS = -Xbatch -showversion -ifdef USE_SUNCC -PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH).suncc +ifeq ($(ZERO_BUILD), true) + PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero else -PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH) + ifdef USE_SUNCC + PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH).suncc + else + PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH) + endif +endif + +# Allow overriding of the arch part of the directory but default +# to BUILDARCH if nothing is specified +ifeq ($(VARIANTARCH),) + VARIANTARCH=$(BUILDARCH) endif ifdef FORCE_TIERED ifeq ($(VARIANT),tiered) -PLATFORM_DIR = $(OS_FAMILY)_$(BUILDARCH)_compiler2 +PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_compiler2 else -PLATFORM_DIR = $(OS_FAMILY)_$(BUILDARCH)_$(VARIANT) +PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_$(VARIANT) endif else -PLATFORM_DIR = $(OS_FAMILY)_$(BUILDARCH)_$(VARIANT) +PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_$(VARIANT) endif # @@ -321,6 +331,7 @@ DATA_MODE/sparc = 32 DATA_MODE/sparcv9 = 64 DATA_MODE/amd64 = 64 DATA_MODE/ia64 = 64 +DATA_MODE/zero = $(ARCH_DATA_MODEL) JAVA_FLAG/32 = -d32 JAVA_FLAG/64 = -d64 diff --git a/hotspot/make/linux/makefiles/defs.make b/hotspot/make/linux/makefiles/defs.make index 2925654e677..f1a8c5dd718 100644 --- a/hotspot/make/linux/makefiles/defs.make +++ b/hotspot/make/linux/makefiles/defs.make @@ -37,6 +37,17 @@ else ARCH_DATA_MODEL ?= 32 endif +# zero +ifeq ($(ZERO_BUILD), true) + ifeq ($(ARCH_DATA_MODEL), 64) + MAKE_ARGS += LP64=1 + endif + PLATFORM = linux-zero + VM_PLATFORM = linux_$(subst i386,i486,$(ZERO_LIBARCH)) + HS_ARCH = zero + ARCH = zero +endif + # ia64 ifeq ($(ARCH), ia64) ARCH_DATA_MODEL = 64 @@ -97,17 +108,19 @@ EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjsig.so EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so -ifeq ($(ARCH_DATA_MODEL), 32) - EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjsig.so - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so - EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so - EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar -else - ifeq ($(ARCH),ia64) - else - EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so - EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar +ifneq ($(ZERO_BUILD), true) + ifeq ($(ARCH_DATA_MODEL), 32) + EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjsig.so + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so + EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar + else + ifeq ($(ARCH),ia64) + else + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so + EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar endif + endif endif diff --git a/hotspot/make/linux/makefiles/gcc.make b/hotspot/make/linux/makefiles/gcc.make index 537ce95ffa0..eeb7cd5dd16 100644 --- a/hotspot/make/linux/makefiles/gcc.make +++ b/hotspot/make/linux/makefiles/gcc.make @@ -52,6 +52,9 @@ VM_PICFLAG/LIBJVM = $(PICFLAG) VM_PICFLAG/AOUT = VM_PICFLAG = $(VM_PICFLAG/$(LINK_INTO)) +ifeq ($(ZERO_BUILD), true) +CFLAGS += $(LIBFFI_CFLAGS) +endif CFLAGS += $(VM_PICFLAG) CFLAGS += -fno-rtti CFLAGS += -fno-exceptions @@ -64,6 +67,7 @@ ARCHFLAG/amd64 = -m64 ARCHFLAG/ia64 = ARCHFLAG/sparc = -m32 -mcpu=v9 ARCHFLAG/sparcv9 = -m64 -mcpu=v9 +ARCHFLAG/zero = $(ZERO_ARCHFLAG) CFLAGS += $(ARCHFLAG) AOUT_FLAGS += $(ARCHFLAG) diff --git a/hotspot/make/linux/makefiles/sa.make b/hotspot/make/linux/makefiles/sa.make index 0b5b5ceff4c..4f3a3ff4ce9 100644 --- a/hotspot/make/linux/makefiles/sa.make +++ b/hotspot/make/linux/makefiles/sa.make @@ -52,10 +52,10 @@ SA_BUILD_VERSION_PROP = "sun.jvm.hotspot.runtime.VM.saBuildVersion=$(SA_BUILD_VE SA_PROPERTIES = $(SA_CLASSDIR)/sa.properties # if $(AGENT_DIR) does not exist, we don't build SA -# also, we don't build SA on Itanium. +# also, we don't build SA on Itanium or zero. all: - if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" ] ; then \ + if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \ $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \ fi diff --git a/hotspot/make/linux/makefiles/saproc.make b/hotspot/make/linux/makefiles/saproc.make index db05d137396..696157969ea 100644 --- a/hotspot/make/linux/makefiles/saproc.make +++ b/hotspot/make/linux/makefiles/saproc.make @@ -49,10 +49,10 @@ ifeq ($(DEBUG_BINARIES), true) endif # if $(AGENT_DIR) does not exist, we don't build SA -# also, we don't build SA on Itanium. +# also, we don't build SA on Itanium or zero. checkAndBuildSA: - $(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" ] ; then \ + $(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \ $(MAKE) -f vm.make $(LIBSAPROC); \ fi diff --git a/hotspot/make/linux/makefiles/top.make b/hotspot/make/linux/makefiles/top.make index e8490fa0327..d85cc052f77 100644 --- a/hotspot/make/linux/makefiles/top.make +++ b/hotspot/make/linux/makefiles/top.make @@ -74,6 +74,7 @@ Include_DBs/CORE = $(VM)/includeDB_core $(Include_DBs/GC) \ Include_DBs/COMPILER1 = $(Include_DBs/CORE) $(VM)/includeDB_compiler1 Include_DBs/COMPILER2 = $(Include_DBs/CORE) $(VM)/includeDB_compiler2 Include_DBs/TIERED = $(Include_DBs/CORE) $(VM)/includeDB_compiler1 $(VM)/includeDB_compiler2 +Include_DBs/ZERO = $(Include_DBs/CORE) $(VM)/includeDB_zero Include_DBs = $(Include_DBs/$(TYPE)) Cached_plat = $(GENERATED)/platform.current diff --git a/hotspot/make/linux/makefiles/vm.make b/hotspot/make/linux/makefiles/vm.make index dc09e17b6ca..641d0d79514 100644 --- a/hotspot/make/linux/makefiles/vm.make +++ b/hotspot/make/linux/makefiles/vm.make @@ -40,7 +40,11 @@ GENERATED = ../generated include $(GENERATED)/Dependencies # read machine-specific adjustments (%%% should do this via buildtree.make?) -include $(MAKEFILES_DIR)/$(BUILDARCH).make +ifeq ($(ZERO_BUILD), true) + include $(MAKEFILES_DIR)/zeroshark.make +else + include $(MAKEFILES_DIR)/$(BUILDARCH).make +endif # set VPATH so make knows where to look for source files # Src_Dirs is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm @@ -124,7 +128,11 @@ mapfile_reorder : mapfile $(REORDERFILE) rm -f $@ cat $^ > $@ -STATIC_CXX = true +ifeq ($(ZERO_LIBARCH), ppc64) + STATIC_CXX = false +else + STATIC_CXX = true +endif ifeq ($(LINK_INTO),AOUT) LIBJVM.o = @@ -148,6 +156,9 @@ else LIBS_VM += $(LIBS) endif +ifeq ($(ZERO_BUILD), true) + LIBS_VM += $(LIBFFI_LIBS) +endif LINK_VM = $(LINK_LIB.c) diff --git a/hotspot/make/linux/makefiles/zero.make b/hotspot/make/linux/makefiles/zero.make new file mode 100644 index 00000000000..fba4cd58131 --- /dev/null +++ b/hotspot/make/linux/makefiles/zero.make @@ -0,0 +1,32 @@ +# +# Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2009 Red Hat, Inc. +# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# +# + +# Setup for Zero (non-Shark) version of VM + +# Select which includeDB files to use (in top.make) +TYPE = ZERO + +# Install libjvm.so, etc in in server directory. +VM_SUBDIR = server diff --git a/hotspot/make/linux/makefiles/zeroshark.make b/hotspot/make/linux/makefiles/zeroshark.make new file mode 100644 index 00000000000..a16cb0ec85a --- /dev/null +++ b/hotspot/make/linux/makefiles/zeroshark.make @@ -0,0 +1,43 @@ +# +# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007, 2008 Red Hat, Inc. +# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# +# + +# Setup common to Zero (non-Shark) and Shark versions of VM + +# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized +OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT) +# The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized +OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT) + +# Specify that the CPU is little endian, if necessary +ifeq ($(ZERO_ENDIANNESS), little) + CFLAGS += -DVM_LITTLE_ENDIAN +endif + +# Specify that the CPU is 64 bit, if necessary +ifeq ($(ARCH_DATA_MODEL), 64) + CFLAGS += -D_LP64=1 +endif + +OPT_CFLAGS/compactingPermGenGen.o = -O1 diff --git a/hotspot/make/linux/platform_zero.in b/hotspot/make/linux/platform_zero.in new file mode 100644 index 00000000000..404ad3f9b58 --- /dev/null +++ b/hotspot/make/linux/platform_zero.in @@ -0,0 +1,17 @@ +os_family = linux + +arch = zero + +arch_model = zero + +os_arch = linux_zero + +os_arch_model = linux_zero + +lib_arch = zero + +compiler = gcc + +gnu_dis_arch = zero + +sysdefs = -DLINUX -D_GNU_SOURCE -DCC_INTERP -DZERO -D@ZERO_ARCHDEF@ -DZERO_LIBARCH=\"@ZERO_LIBARCH@\" diff --git a/hotspot/src/cpu/zero/vm/assembler_zero.cpp b/hotspot/src/cpu/zero/vm/assembler_zero.cpp new file mode 100644 index 00000000000..808069a5825 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/assembler_zero.cpp @@ -0,0 +1,77 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_assembler_zero.cpp.incl" + +int AbstractAssembler::code_fill_byte() { + return 0; +} + +void Assembler::pd_patch_instruction(address branch, address target) { + ShouldNotCallThis(); +} + +#ifndef PRODUCT +void Assembler::pd_print_patched_instruction(address branch) { + ShouldNotCallThis(); +} +#endif // PRODUCT + +void MacroAssembler::align(int modulus) { + while (offset() % modulus != 0) + emit_byte(AbstractAssembler::code_fill_byte()); +} + +void MacroAssembler::bang_stack_with_offset(int offset) { + ShouldNotCallThis(); +} + +void MacroAssembler::advance(int bytes) { + _code_pos += bytes; + sync(); +} + +RegisterOrConstant MacroAssembler::delayed_value_impl( + intptr_t* delayed_value_addr, Register tmpl, int offset) { + ShouldNotCallThis(); +} + +void MacroAssembler::store_oop(jobject obj) { + code_section()->relocate(pc(), oop_Relocation::spec_for_immediate()); + emit_address((address) obj); +} + +static void should_not_call() { + report_should_not_call(__FILE__, __LINE__); +} + +address ShouldNotCallThisStub() { + return (address) should_not_call; +} + +address ShouldNotCallThisEntry() { + return (address) should_not_call; +} diff --git a/hotspot/src/cpu/zero/vm/assembler_zero.hpp b/hotspot/src/cpu/zero/vm/assembler_zero.hpp new file mode 100644 index 00000000000..bf2227768cb --- /dev/null +++ b/hotspot/src/cpu/zero/vm/assembler_zero.hpp @@ -0,0 +1,64 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// In normal, CPU-specific ports of HotSpot these two classes are used +// for generating assembly language. We don't do any of this in zero, +// of course, but we do sneak entry points around in CodeBuffers so we +// generate those here. + +class Assembler : public AbstractAssembler { + public: + Assembler(CodeBuffer* code) : AbstractAssembler(code) {} + + public: + void pd_patch_instruction(address branch, address target); +#ifndef PRODUCT + static void pd_print_patched_instruction(address branch); +#endif // PRODUCT +}; + +class MacroAssembler : public Assembler { + public: + MacroAssembler(CodeBuffer* code) : Assembler(code) {} + + public: + void align(int modulus); + void bang_stack_with_offset(int offset); + bool needs_explicit_null_check(intptr_t offset); + RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, + Register tmp, int offset); + public: + void advance(int bytes); + void store_oop(jobject obj); +}; + +#ifdef ASSERT +inline bool AbstractAssembler::pd_check_instruction_mark() { + ShouldNotCallThis(); +} +#endif + +address ShouldNotCallThisStub(); +address ShouldNotCallThisEntry(); diff --git a/hotspot/src/cpu/zero/vm/assembler_zero.inline.hpp b/hotspot/src/cpu/zero/vm/assembler_zero.inline.hpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/assembler_zero.inline.hpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.cpp b/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.cpp new file mode 100644 index 00000000000..d9bef216880 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_cppInterpreter_zero.cpp.incl" + +#ifdef CC_INTERP + +const char *BytecodeInterpreter::name_of_field_at_address(address addr) { +#define DO(member) {if (addr == (address) &(member)) return XSTR(member);} + DO(_thread); + DO(_bcp); + DO(_locals); + DO(_constants); + DO(_method); + DO(_mdx); + DO(_stack); + DO(_msg); + DO(_result); + DO(_prev_link); + DO(_oop_temp); + DO(_stack_base); + DO(_stack_limit); + DO(_monitor_base); + DO(_self_link); +#undef DO + if (addr > (address) &_result && addr < (address) (&_result + 1)) + return "_result)"; + return NULL; +} + +#endif // CC_INTERP diff --git a/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp b/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp new file mode 100644 index 00000000000..33649b20b96 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp @@ -0,0 +1,148 @@ +/* + * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Platform specific for C++ based Interpreter + +#if defined(PPC) || defined(SPARC) || defined(IA64) +#define LOTS_OF_REGS // Use plenty of registers +#else +#undef LOTS_OF_REGS // Loser platforms +#endif + + private: + interpreterState _self_link; + + public: + inline void set_locals(intptr_t* new_locals) { + _locals = new_locals; + } + inline void set_method(methodOop new_method) { + _method = new_method; + } + inline interpreterState self_link() { + return _self_link; + } + inline void set_self_link(interpreterState new_self_link) { + _self_link = new_self_link; + } + inline interpreterState prev_link() { + return _prev_link; + } + inline void set_prev_link(interpreterState new_prev_link) { + _prev_link = new_prev_link; + } + inline void set_stack_limit(intptr_t* new_stack_limit) { + _stack_limit = new_stack_limit; + } + inline void set_stack_base(intptr_t* new_stack_base) { + _stack_base = new_stack_base; + } + inline void set_monitor_base(BasicObjectLock *new_monitor_base) { + _monitor_base = new_monitor_base; + } + inline void set_thread(JavaThread* new_thread) { + _thread = new_thread; + } + inline void set_constants(constantPoolCacheOop new_constants) { + _constants = new_constants; + } + inline oop oop_temp() { + return _oop_temp; + } + inline oop *oop_temp_addr() { + return &_oop_temp; + } + inline void set_oop_temp(oop new_oop_temp) { + _oop_temp = new_oop_temp; + } + inline address callee_entry_point() { + return _result._to_call._callee_entry_point; + } + inline address osr_buf() { + return _result._osr._osr_buf; + } + inline address osr_entry() { + return _result._osr._osr_entry; + } + + public: + const char *name_of_field_at_address(address addr); + +// The frame manager handles this +#define SET_LAST_JAVA_FRAME() +#define RESET_LAST_JAVA_FRAME() + +// ZeroStack Implementation + +#undef STACK_INT +#undef STACK_FLOAT +#undef STACK_ADDR +#undef STACK_OBJECT +#undef STACK_DOUBLE +#undef STACK_LONG + +#define GET_STACK_SLOT(offset) (*((intptr_t*) &topOfStack[-(offset)])) +#define STACK_SLOT(offset) ((address) &topOfStack[-(offset)]) +#define STACK_ADDR(offset) (*((address *) &topOfStack[-(offset)])) +#define STACK_INT(offset) (*((jint*) &topOfStack[-(offset)])) +#define STACK_FLOAT(offset) (*((jfloat *) &topOfStack[-(offset)])) +#define STACK_OBJECT(offset) (*((oop *) &topOfStack [-(offset)])) +#define STACK_DOUBLE(offset) (((VMJavaVal64*) &topOfStack[-(offset)])->d) +#define STACK_LONG(offset) (((VMJavaVal64 *) &topOfStack[-(offset)])->l) + +#define SET_STACK_SLOT(value, offset) (*(intptr_t*)&topOfStack[-(offset)] = *(intptr_t*)(value)) +#define SET_STACK_ADDR(value, offset) (*((address *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_INT(value, offset) (*((jint *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_FLOAT(value, offset) (*((jfloat *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_OBJECT(value, offset) (*((oop *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_DOUBLE(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = (value)) +#define SET_STACK_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = \ + ((VMJavaVal64*)(addr))->d) +#define SET_STACK_LONG(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = (value)) +#define SET_STACK_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = \ + ((VMJavaVal64*)(addr))->l) +// JavaLocals implementation + +#define LOCALS_SLOT(offset) ((intptr_t*)&locals[-(offset)]) +#define LOCALS_ADDR(offset) ((address)locals[-(offset)]) +#define LOCALS_INT(offset) (*((jint*)&locals[-(offset)])) +#define LOCALS_FLOAT(offset) (*((jfloat*)&locals[-(offset)])) +#define LOCALS_OBJECT(offset) ((oop)locals[-(offset)]) +#define LOCALS_DOUBLE(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->d) +#define LOCALS_LONG(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->l) +#define LOCALS_LONG_AT(offset) (((address)&locals[-((offset) + 1)])) +#define LOCALS_DOUBLE_AT(offset) (((address)&locals[-((offset) + 1)])) + +#define SET_LOCALS_SLOT(value, offset) (*(intptr_t*)&locals[-(offset)] = *(intptr_t *)(value)) +#define SET_LOCALS_ADDR(value, offset) (*((address *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_INT(value, offset) (*((jint *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_FLOAT(value, offset) (*((jfloat *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_OBJECT(value, offset) (*((oop *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_DOUBLE(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = (value)) +#define SET_LOCALS_LONG(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = (value)) +#define SET_LOCALS_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = \ + ((VMJavaVal64*)(addr))->d) +#define SET_LOCALS_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = \ + ((VMJavaVal64*)(addr))->l) diff --git a/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp b/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp new file mode 100644 index 00000000000..33b5d0a931b --- /dev/null +++ b/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp @@ -0,0 +1,301 @@ +/* + * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Inline interpreter functions for zero + +inline jfloat BytecodeInterpreter::VMfloatAdd(jfloat op1, jfloat op2) { + return op1 + op2; +} + +inline jfloat BytecodeInterpreter::VMfloatSub(jfloat op1, jfloat op2) { + return op1 - op2; +} + +inline jfloat BytecodeInterpreter::VMfloatMul(jfloat op1, jfloat op2) { + return op1 * op2; +} + +inline jfloat BytecodeInterpreter::VMfloatDiv(jfloat op1, jfloat op2) { + return op1 / op2; +} + +inline jfloat BytecodeInterpreter::VMfloatRem(jfloat op1, jfloat op2) { + return fmod(op1, op2); +} + +inline jfloat BytecodeInterpreter::VMfloatNeg(jfloat op) { + return -op; +} + +inline int32_t BytecodeInterpreter::VMfloatCompare(jfloat op1, + jfloat op2, + int32_t direction) { + return ( op1 < op2 ? -1 : + op1 > op2 ? 1 : + op1 == op2 ? 0 : + (direction == -1 || direction == 1) ? direction : 0); + +} + +inline void BytecodeInterpreter::VMmemCopy64(uint32_t to[2], + const uint32_t from[2]) { + *(uint64_t *) to = *(uint64_t *) from; +} + +inline jlong BytecodeInterpreter::VMlongAdd(jlong op1, jlong op2) { + return op1 + op2; +} + +inline jlong BytecodeInterpreter::VMlongAnd(jlong op1, jlong op2) { + return op1 & op2; +} + +inline jlong BytecodeInterpreter::VMlongDiv(jlong op1, jlong op2) { + /* it's possible we could catch this special case implicitly */ + if (op1 == (jlong) 0x8000000000000000LL && op2 == -1) return op1; + else return op1 / op2; +} + +inline jlong BytecodeInterpreter::VMlongMul(jlong op1, jlong op2) { + return op1 * op2; +} + +inline jlong BytecodeInterpreter::VMlongOr(jlong op1, jlong op2) { + return op1 | op2; +} + +inline jlong BytecodeInterpreter::VMlongSub(jlong op1, jlong op2) { + return op1 - op2; +} + +inline jlong BytecodeInterpreter::VMlongXor(jlong op1, jlong op2) { + return op1 ^ op2; +} + +inline jlong BytecodeInterpreter::VMlongRem(jlong op1, jlong op2) { + /* it's possible we could catch this special case implicitly */ + if (op1 == (jlong) 0x8000000000000000LL && op2 == -1) return 0; + else return op1 % op2; +} + +inline jlong BytecodeInterpreter::VMlongUshr(jlong op1, jint op2) { + return ((unsigned long long) op1) >> (op2 & 0x3F); +} + +inline jlong BytecodeInterpreter::VMlongShr(jlong op1, jint op2) { + return op1 >> (op2 & 0x3F); +} + +inline jlong BytecodeInterpreter::VMlongShl(jlong op1, jint op2) { + return op1 << (op2 & 0x3F); +} + +inline jlong BytecodeInterpreter::VMlongNeg(jlong op) { + return -op; +} + +inline jlong BytecodeInterpreter::VMlongNot(jlong op) { + return ~op; +} + +inline int32_t BytecodeInterpreter::VMlongLtz(jlong op) { + return (op <= 0); +} + +inline int32_t BytecodeInterpreter::VMlongGez(jlong op) { + return (op >= 0); +} + +inline int32_t BytecodeInterpreter::VMlongEqz(jlong op) { + return (op == 0); +} + +inline int32_t BytecodeInterpreter::VMlongEq(jlong op1, jlong op2) { + return (op1 == op2); +} + +inline int32_t BytecodeInterpreter::VMlongNe(jlong op1, jlong op2) { + return (op1 != op2); +} + +inline int32_t BytecodeInterpreter::VMlongGe(jlong op1, jlong op2) { + return (op1 >= op2); +} + +inline int32_t BytecodeInterpreter::VMlongLe(jlong op1, jlong op2) { + return (op1 <= op2); +} + +inline int32_t BytecodeInterpreter::VMlongLt(jlong op1, jlong op2) { + return (op1 < op2); +} + +inline int32_t BytecodeInterpreter::VMlongGt(jlong op1, jlong op2) { + return (op1 > op2); +} + +inline int32_t BytecodeInterpreter::VMlongCompare(jlong op1, jlong op2) { + return (VMlongLt(op1, op2) ? -1 : VMlongGt(op1, op2) ? 1 : 0); +} + +// Long conversions + +inline jdouble BytecodeInterpreter::VMlong2Double(jlong val) { + return (jdouble) val; +} + +inline jfloat BytecodeInterpreter::VMlong2Float(jlong val) { + return (jfloat) val; +} + +inline jint BytecodeInterpreter::VMlong2Int(jlong val) { + return (jint) val; +} + +// Double Arithmetic + +inline jdouble BytecodeInterpreter::VMdoubleAdd(jdouble op1, jdouble op2) { + return op1 + op2; +} + +inline jdouble BytecodeInterpreter::VMdoubleDiv(jdouble op1, jdouble op2) { + // Divide by zero... QQQ + return op1 / op2; +} + +inline jdouble BytecodeInterpreter::VMdoubleMul(jdouble op1, jdouble op2) { + return op1 * op2; +} + +inline jdouble BytecodeInterpreter::VMdoubleNeg(jdouble op) { + return -op; +} + +inline jdouble BytecodeInterpreter::VMdoubleRem(jdouble op1, jdouble op2) { + return fmod(op1, op2); +} + +inline jdouble BytecodeInterpreter::VMdoubleSub(jdouble op1, jdouble op2) { + return op1 - op2; +} + +inline int32_t BytecodeInterpreter::VMdoubleCompare(jdouble op1, + jdouble op2, + int32_t direction) { + return ( op1 < op2 ? -1 : + op1 > op2 ? 1 : + op1 == op2 ? 0 : + (direction == -1 || direction == 1) ? direction : 0); +} + +// Double Conversions + +inline jfloat BytecodeInterpreter::VMdouble2Float(jdouble val) { + return (jfloat) val; +} + +// Float Conversions + +inline jdouble BytecodeInterpreter::VMfloat2Double(jfloat op) { + return (jdouble) op; +} + +// Integer Arithmetic + +inline jint BytecodeInterpreter::VMintAdd(jint op1, jint op2) { + return op1 + op2; +} + +inline jint BytecodeInterpreter::VMintAnd(jint op1, jint op2) { + return op1 & op2; +} + +inline jint BytecodeInterpreter::VMintDiv(jint op1, jint op2) { + /* it's possible we could catch this special case implicitly */ + if (op1 == (jint) 0x80000000 && op2 == -1) return op1; + else return op1 / op2; +} + +inline jint BytecodeInterpreter::VMintMul(jint op1, jint op2) { + return op1 * op2; +} + +inline jint BytecodeInterpreter::VMintNeg(jint op) { + return -op; +} + +inline jint BytecodeInterpreter::VMintOr(jint op1, jint op2) { + return op1 | op2; +} + +inline jint BytecodeInterpreter::VMintRem(jint op1, jint op2) { + /* it's possible we could catch this special case implicitly */ + if (op1 == (jint) 0x80000000 && op2 == -1) return 0; + else return op1 % op2; +} + +inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) { + return op1 << (op2 & 0x1F); +} + +inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) { + return op1 >> (op2 & 0x1F); +} + +inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) { + return op1 - op2; +} + +inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) { + return ((juint) op1) >> (op2 & 0x1F); +} + +inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) { + return op1 ^ op2; +} + +inline jdouble BytecodeInterpreter::VMint2Double(jint val) { + return (jdouble) val; +} + +inline jfloat BytecodeInterpreter::VMint2Float(jint val) { + return (jfloat) val; +} + +inline jlong BytecodeInterpreter::VMint2Long(jint val) { + return (jlong) val; +} + +inline jchar BytecodeInterpreter::VMint2Char(jint val) { + return (jchar) val; +} + +inline jshort BytecodeInterpreter::VMint2Short(jint val) { + return (jshort) val; +} + +inline jbyte BytecodeInterpreter::VMint2Byte(jint val) { + return (jbyte) val; +} diff --git a/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp b/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp new file mode 100644 index 00000000000..471c0202c87 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_bytecodes_zero.cpp.incl" + +void Bytecodes::pd_initialize() { + // No zero specific initialization +} diff --git a/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp b/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/bytes_zero.hpp b/hotspot/src/cpu/zero/vm/bytes_zero.hpp new file mode 100644 index 00000000000..d69c28e28af --- /dev/null +++ b/hotspot/src/cpu/zero/vm/bytes_zero.hpp @@ -0,0 +1,164 @@ +/* + * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +typedef union unaligned { + u4 u; + u2 us; + u8 ul; +} __attribute__((packed)) unaligned; + +class Bytes: AllStatic { + public: + // Returns true if the byte ordering used by Java is different + // from the native byte ordering of the underlying machine. + static inline bool is_Java_byte_ordering_different() { +#ifdef VM_LITTLE_ENDIAN + return true; +#else + return false; +#endif + } + + // Efficient reading and writing of unaligned unsigned data in + // platform-specific byte ordering. + static inline u2 get_native_u2(address p){ + unaligned *up = (unaligned *) p; + return up->us; + } + + static inline u4 get_native_u4(address p) { + unaligned *up = (unaligned *) p; + return up->u; + } + + static inline u8 get_native_u8(address p) { + unaligned *up = (unaligned *) p; + return up->ul; + } + + static inline void put_native_u2(address p, u2 x) { + unaligned *up = (unaligned *) p; + up->us = x; + } + + static inline void put_native_u4(address p, u4 x) { + unaligned *up = (unaligned *) p; + up->u = x; + } + + static inline void put_native_u8(address p, u8 x) { + unaligned *up = (unaligned *) p; + up->ul = x; + } + + // Efficient reading and writing of unaligned unsigned data in Java + // byte ordering (i.e. big-endian ordering). +#ifdef VM_LITTLE_ENDIAN + // Byte-order reversal is needed + static inline u2 get_Java_u2(address p) { + return (u2(p[0]) << 8) | + (u2(p[1]) ); + } + static inline u4 get_Java_u4(address p) { + return (u4(p[0]) << 24) | + (u4(p[1]) << 16) | + (u4(p[2]) << 8) | + (u4(p[3]) ); + } + static inline u8 get_Java_u8(address p) { + u4 hi, lo; + hi = (u4(p[0]) << 24) | + (u4(p[1]) << 16) | + (u4(p[2]) << 8) | + (u4(p[3]) ); + lo = (u4(p[4]) << 24) | + (u4(p[5]) << 16) | + (u4(p[6]) << 8) | + (u4(p[7]) ); + return u8(lo) | (u8(hi) << 32); + } + + static inline void put_Java_u2(address p, u2 x) { + p[0] = x >> 8; + p[1] = x; + } + static inline void put_Java_u4(address p, u4 x) { + p[0] = x >> 24; + p[1] = x >> 16; + p[2] = x >> 8; + p[3] = x; + } + static inline void put_Java_u8(address p, u8 x) { + u4 hi, lo; + lo = x; + hi = x >> 32; + p[0] = hi >> 24; + p[1] = hi >> 16; + p[2] = hi >> 8; + p[3] = hi; + p[4] = lo >> 24; + p[5] = lo >> 16; + p[6] = lo >> 8; + p[7] = lo; + } + + // Efficient swapping of byte ordering + static inline u2 swap_u2(u2 x); + static inline u4 swap_u4(u4 x); + static inline u8 swap_u8(u8 x); +#else + // No byte-order reversal is needed + static inline u2 get_Java_u2(address p) { + return get_native_u2(p); + } + static inline u4 get_Java_u4(address p) { + return get_native_u4(p); + } + static inline u8 get_Java_u8(address p) { + return get_native_u8(p); + } + + static inline void put_Java_u2(address p, u2 x) { + put_native_u2(p, x); + } + static inline void put_Java_u4(address p, u4 x) { + put_native_u4(p, x); + } + static inline void put_Java_u8(address p, u8 x) { + put_native_u8(p, x); + } + + // No byte-order reversal is needed + static inline u2 swap_u2(u2 x) { return x; } + static inline u4 swap_u4(u4 x) { return x; } + static inline u8 swap_u8(u8 x) { return x; } +#endif // VM_LITTLE_ENDIAN +}; + +#ifdef VM_LITTLE_ENDIAN +// The following header contains the implementations of swap_u2, +// swap_u4, and swap_u8 +#include "incls/_bytes_pd.inline.hpp.incl" +#endif // VM_LITTLE_ENDIAN diff --git a/hotspot/src/cpu/zero/vm/codeBuffer_zero.hpp b/hotspot/src/cpu/zero/vm/codeBuffer_zero.hpp new file mode 100644 index 00000000000..b89764ac65b --- /dev/null +++ b/hotspot/src/cpu/zero/vm/codeBuffer_zero.hpp @@ -0,0 +1,27 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + private: + void pd_initialize() {} diff --git a/hotspot/src/cpu/zero/vm/copy_zero.hpp b/hotspot/src/cpu/zero/vm/copy_zero.hpp new file mode 100644 index 00000000000..f8824eb300f --- /dev/null +++ b/hotspot/src/cpu/zero/vm/copy_zero.hpp @@ -0,0 +1,178 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Inline functions for memory copy and fill. + +static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) { + memmove(to, from, count * HeapWordSize); +} + +static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) { + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: + memcpy(to, from, count * HeapWordSize); + break; + } +} + +static void pd_disjoint_words_atomic(HeapWord* from, + HeapWord* to, + size_t count) { + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: + while (count-- > 0) { + *to++ = *from++; + } + break; + } +} + +static void pd_aligned_conjoint_words(HeapWord* from, + HeapWord* to, + size_t count) { + memmove(to, from, count * HeapWordSize); +} + +static void pd_aligned_disjoint_words(HeapWord* from, + HeapWord* to, + size_t count) { + pd_disjoint_words(from, to, count); +} + +static void pd_conjoint_bytes(void* from, void* to, size_t count) { + memmove(to, from, count); +} + +static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) { + memmove(to, from, count); +} + +static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) { + _Copy_conjoint_jshorts_atomic(from, to, count); +} + +static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) { + _Copy_conjoint_jints_atomic(from, to, count); +} + +static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) { + _Copy_conjoint_jlongs_atomic(from, to, count); +} + +static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) { +#ifdef _LP64 + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count); +#else + assert(BytesPerInt == BytesPerOop, "jints and oops must be the same size"); + _Copy_conjoint_jints_atomic((jint*)from, (jint*)to, count); +#endif // _LP64 +} + +static void pd_arrayof_conjoint_bytes(HeapWord* from, + HeapWord* to, + size_t count) { + _Copy_arrayof_conjoint_bytes(from, to, count); +} + +static void pd_arrayof_conjoint_jshorts(HeapWord* from, + HeapWord* to, + size_t count) { + _Copy_arrayof_conjoint_jshorts(from, to, count); +} + +static void pd_arrayof_conjoint_jints(HeapWord* from, + HeapWord* to, + size_t count) { + _Copy_arrayof_conjoint_jints(from, to, count); +} + +static void pd_arrayof_conjoint_jlongs(HeapWord* from, + HeapWord* to, + size_t count) { + _Copy_arrayof_conjoint_jlongs(from, to, count); +} + +static void pd_arrayof_conjoint_oops(HeapWord* from, + HeapWord* to, + size_t count) { +#ifdef _LP64 + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_arrayof_conjoint_jlongs(from, to, count); +#else + assert(BytesPerInt == BytesPerOop, "jints and oops must be the same size"); + _Copy_arrayof_conjoint_jints(from, to, count); +#endif // _LP64 +} + +static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) { +#ifdef _LP64 + julong* to = (julong*) tohw; + julong v = ((julong) value << 32) | value; +#else + juint* to = (juint*) tohw; + juint v = value; +#endif // _LP64 + + while (count-- > 0) { + *to++ = v; + } +} + +static void pd_fill_to_aligned_words(HeapWord* tohw, + size_t count, + juint value) { + pd_fill_to_words(tohw, count, value); +} + +static void pd_fill_to_bytes(void* to, size_t count, jubyte value) { + memset(to, value, count); +} + +static void pd_zero_to_words(HeapWord* tohw, size_t count) { + pd_fill_to_words(tohw, count, 0); +} + +static void pd_zero_to_bytes(void* to, size_t count) { + memset(to, 0, count); +} diff --git a/hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp b/hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp new file mode 100644 index 00000000000..7861f3aa5d8 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp @@ -0,0 +1,37 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + protected: + MacroAssembler* assembler() const { + return _masm; + } + + protected: + address generate_entry(address entry_point) { + ZeroEntry *entry = (ZeroEntry *) assembler()->pc(); + assembler()->advance(sizeof(ZeroEntry)); + entry->set_entry_point(entry_point); + return (address) entry; + } diff --git a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp new file mode 100644 index 00000000000..8c99fbf4556 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp @@ -0,0 +1,946 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_cppInterpreter_zero.cpp.incl" + +#ifdef CC_INTERP + +#define fixup_after_potential_safepoint() \ + method = istate->method() + +#define CALL_VM_NOCHECK(func) \ + thread->set_last_Java_frame(); \ + func; \ + thread->reset_last_Java_frame(); \ + fixup_after_potential_safepoint() + +void CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) { + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + + // Adjust the caller's stack frame to accomodate any additional + // local variables we have contiguously with our parameters. + int extra_locals = method->max_locals() - method->size_of_parameters(); + if (extra_locals > 0) { + if (extra_locals > stack->available_words()) { + Unimplemented(); + } + for (int i = 0; i < extra_locals; i++) + stack->push(0); + } + + // Allocate and initialize our frame. + InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread); + thread->push_zero_frame(frame); + + // Execute those bytecodes! + main_loop(0, THREAD); +} + +void CppInterpreter::main_loop(int recurse, TRAPS) { + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + + // If we are entering from a deopt we may need to call + // ourself a few times in order to get to our frame. + if (recurse) + main_loop(recurse - 1, THREAD); + + InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); + interpreterState istate = frame->interpreter_state(); + methodOop method = istate->method(); + + intptr_t *result = NULL; + int result_slots = 0; + + // Check we're not about to run out of stack + if (stack_overflow_imminent(thread)) { + CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread)); + goto unwind_and_return; + } + + while (true) { + // We can set up the frame anchor with everything we want at + // this point as we are thread_in_Java and no safepoints can + // occur until we go to vm mode. We do have to clear flags + // on return from vm but that is it. + thread->set_last_Java_frame(); + + // Call the interpreter + if (JvmtiExport::can_post_interpreter_events()) + BytecodeInterpreter::runWithChecks(istate); + else + BytecodeInterpreter::run(istate); + fixup_after_potential_safepoint(); + + // Clear the frame anchor + thread->reset_last_Java_frame(); + + // Examine the message from the interpreter to decide what to do + if (istate->msg() == BytecodeInterpreter::call_method) { + methodOop callee = istate->callee(); + + // Trim back the stack to put the parameters at the top + stack->set_sp(istate->stack() + 1); + + // Make the call + Interpreter::invoke_method(callee, istate->callee_entry_point(), THREAD); + fixup_after_potential_safepoint(); + + // Convert the result + istate->set_stack(stack->sp() - 1); + + // Restore the stack + stack->set_sp(istate->stack_limit() + 1); + + // Resume the interpreter + istate->set_msg(BytecodeInterpreter::method_resume); + } + else if (istate->msg() == BytecodeInterpreter::more_monitors) { + int monitor_words = frame::interpreter_frame_monitor_size(); + + // Allocate the space + if (monitor_words > stack->available_words()) { + Unimplemented(); + } + stack->alloc(monitor_words * wordSize); + + // Move the expression stack contents + for (intptr_t *p = istate->stack() + 1; p < istate->stack_base(); p++) + *(p - monitor_words) = *p; + + // Move the expression stack pointers + istate->set_stack_limit(istate->stack_limit() - monitor_words); + istate->set_stack(istate->stack() - monitor_words); + istate->set_stack_base(istate->stack_base() - monitor_words); + + // Zero the new monitor so the interpreter can find it. + ((BasicObjectLock *) istate->stack_base())->set_obj(NULL); + + // Resume the interpreter + istate->set_msg(BytecodeInterpreter::got_monitors); + } + else if (istate->msg() == BytecodeInterpreter::return_from_method) { + // Copy the result into the caller's frame + result_slots = type2size[method->result_type()]; + assert(result_slots >= 0 && result_slots <= 2, "what?"); + result = istate->stack() + result_slots; + break; + } + else if (istate->msg() == BytecodeInterpreter::throwing_exception) { + assert(HAS_PENDING_EXCEPTION, "should do"); + break; + } + else if (istate->msg() == BytecodeInterpreter::do_osr) { + // Unwind the current frame + thread->pop_zero_frame(); + + // Remove any extension of the previous frame + int extra_locals = method->max_locals() - method->size_of_parameters(); + stack->set_sp(stack->sp() + extra_locals); + + // Jump into the OSR method + Interpreter::invoke_osr( + method, istate->osr_entry(), istate->osr_buf(), THREAD); + return; + } + else { + ShouldNotReachHere(); + } + } + + unwind_and_return: + + // Unwind the current frame + thread->pop_zero_frame(); + + // Pop our local variables + stack->set_sp(stack->sp() + method->max_locals()); + + // Push our result + for (int i = 0; i < result_slots; i++) + stack->push(result[-i]); +} + +void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) { + // Make sure method is native and not abstract + assert(method->is_native() && !method->is_abstract(), "should be"); + + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + + // Allocate and initialize our frame + InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread); + thread->push_zero_frame(frame); + interpreterState istate = frame->interpreter_state(); + intptr_t *locals = istate->locals(); + + // Check we're not about to run out of stack + if (stack_overflow_imminent(thread)) { + CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread)); + goto unwind_and_return; + } + + // Lock if necessary + BasicObjectLock *monitor; + monitor = NULL; + if (method->is_synchronized()) { + monitor = (BasicObjectLock*) istate->stack_base(); + oop lockee = monitor->obj(); + markOop disp = lockee->mark()->set_unlocked(); + + monitor->lock()->set_displaced_header(disp); + if (Atomic::cmpxchg_ptr(monitor, lockee->mark_addr(), disp) != disp) { + if (thread->is_lock_owned((address) disp->clear_lock_bits())) { + monitor->lock()->set_displaced_header(NULL); + } + else { + CALL_VM_NOCHECK(InterpreterRuntime::monitorenter(thread, monitor)); + if (HAS_PENDING_EXCEPTION) + goto unwind_and_return; + } + } + } + + // Get the signature handler + InterpreterRuntime::SignatureHandler *handler; { + address handlerAddr = method->signature_handler(); + if (handlerAddr == NULL) { + CALL_VM_NOCHECK(InterpreterRuntime::prepare_native_call(thread, method)); + if (HAS_PENDING_EXCEPTION) + goto unwind_and_return; + + handlerAddr = method->signature_handler(); + assert(handlerAddr != NULL, "eh?"); + } + if (handlerAddr == (address) InterpreterRuntime::slow_signature_handler) { + CALL_VM_NOCHECK(handlerAddr = + InterpreterRuntime::slow_signature_handler(thread, method, NULL,NULL)); + if (HAS_PENDING_EXCEPTION) + goto unwind_and_return; + } + handler = \ + InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr); + } + + // Get the native function entry point + address function; + function = method->native_function(); + assert(function != NULL, "should be set if signature handler is"); + + // Build the argument list + if (handler->argument_count() * 2 > stack->available_words()) { + Unimplemented(); + } + void **arguments; + void *mirror; { + arguments = + (void **) stack->alloc(handler->argument_count() * sizeof(void **)); + void **dst = arguments; + + void *env = thread->jni_environment(); + *(dst++) = &env; + + if (method->is_static()) { + istate->set_oop_temp( + method->constants()->pool_holder()->klass_part()->java_mirror()); + mirror = istate->oop_temp_addr(); + *(dst++) = &mirror; + } + + intptr_t *src = locals; + for (int i = dst - arguments; i < handler->argument_count(); i++) { + ffi_type *type = handler->argument_type(i); + if (type == &ffi_type_pointer) { + if (*src) { + stack->push((intptr_t) src); + *(dst++) = stack->sp(); + } + else { + *(dst++) = src; + } + src--; + } + else if (type->size == 4) { + *(dst++) = src--; + } + else if (type->size == 8) { + src--; + *(dst++) = src--; + } + else { + ShouldNotReachHere(); + } + } + } + + // Set up the Java frame anchor + thread->set_last_Java_frame(); + + // Change the thread state to _thread_in_native + ThreadStateTransition::transition_from_java(thread, _thread_in_native); + + // Make the call + intptr_t result[4 - LogBytesPerWord]; + ffi_call(handler->cif(), (void (*)()) function, result, arguments); + + // Change the thread state back to _thread_in_Java. + // ThreadStateTransition::transition_from_native() cannot be used + // here because it does not check for asynchronous exceptions. + // We have to manage the transition ourself. + thread->set_thread_state(_thread_in_native_trans); + + // Make sure new state is visible in the GC thread + if (os::is_MP()) { + if (UseMembar) { + OrderAccess::fence(); + } + else { + InterfaceSupport::serialize_memory(thread); + } + } + + // Handle safepoint operations, pending suspend requests, + // and pending asynchronous exceptions. + if (SafepointSynchronize::do_call_back() || + thread->has_special_condition_for_native_trans()) { + JavaThread::check_special_condition_for_native_trans(thread); + CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops()); + } + + // Finally we can change the thread state to _thread_in_Java. + thread->set_thread_state(_thread_in_Java); + fixup_after_potential_safepoint(); + + // Clear the frame anchor + thread->reset_last_Java_frame(); + + // If the result was an oop then unbox it and store it in + // oop_temp where the garbage collector can see it before + // we release the handle it might be protected by. + if (handler->result_type() == &ffi_type_pointer) { + if (result[0]) + istate->set_oop_temp(*(oop *) result[0]); + else + istate->set_oop_temp(NULL); + } + + // Reset handle block + thread->active_handles()->clear(); + + // Unlock if necessary. It seems totally wrong that this + // is skipped in the event of an exception but apparently + // the template interpreter does this so we do too. + if (monitor && !HAS_PENDING_EXCEPTION) { + BasicLock *lock = monitor->lock(); + markOop header = lock->displaced_header(); + oop rcvr = monitor->obj(); + monitor->set_obj(NULL); + + if (header != NULL) { + if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) { + monitor->set_obj(rcvr); { + HandleMark hm(thread); + CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(thread, monitor)); + } + } + } + } + + unwind_and_return: + + // Unwind the current activation + thread->pop_zero_frame(); + + // Pop our parameters + stack->set_sp(stack->sp() + method->size_of_parameters()); + + // Push our result + if (!HAS_PENDING_EXCEPTION) { + stack->set_sp(stack->sp() - type2size[method->result_type()]); + + switch (method->result_type()) { + case T_VOID: + break; + + case T_BOOLEAN: +#ifndef VM_LITTLE_ENDIAN + result[0] <<= (BitsPerWord - BitsPerByte); +#endif + SET_LOCALS_INT(*(jboolean *) result != 0, 0); + break; + + case T_CHAR: +#ifndef VM_LITTLE_ENDIAN + result[0] <<= (BitsPerWord - BitsPerShort); +#endif + SET_LOCALS_INT(*(jchar *) result, 0); + break; + + case T_BYTE: +#ifndef VM_LITTLE_ENDIAN + result[0] <<= (BitsPerWord - BitsPerByte); +#endif + SET_LOCALS_INT(*(jbyte *) result, 0); + break; + + case T_SHORT: +#ifndef VM_LITTLE_ENDIAN + result[0] <<= (BitsPerWord - BitsPerShort); +#endif + SET_LOCALS_INT(*(jshort *) result, 0); + break; + + case T_INT: +#ifndef VM_LITTLE_ENDIAN + result[0] <<= (BitsPerWord - BitsPerInt); +#endif + SET_LOCALS_INT(*(jint *) result, 0); + break; + + case T_LONG: + SET_LOCALS_LONG(*(jlong *) result, 0); + break; + + case T_FLOAT: + SET_LOCALS_FLOAT(*(jfloat *) result, 0); + break; + + case T_DOUBLE: + SET_LOCALS_DOUBLE(*(jdouble *) result, 0); + break; + + case T_OBJECT: + case T_ARRAY: + SET_LOCALS_OBJECT(istate->oop_temp(), 0); + break; + + default: + ShouldNotReachHere(); + } + } +} + +void CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) { + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + intptr_t *locals = stack->sp(); + + // Drop into the slow path if we need a safepoint check + if (SafepointSynchronize::do_call_back()) { + normal_entry(method, 0, THREAD); + return; + } + + // Load the object pointer and drop into the slow path + // if we have a NullPointerException + oop object = LOCALS_OBJECT(0); + if (object == NULL) { + normal_entry(method, 0, THREAD); + return; + } + + // Read the field index from the bytecode, which looks like this: + // 0: aload_0 + // 1: getfield + // 2: index + // 3: index + // 4: ireturn/areturn + // NB this is not raw bytecode: index is in machine order + u1 *code = method->code_base(); + assert(code[0] == Bytecodes::_aload_0 && + code[1] == Bytecodes::_getfield && + (code[4] == Bytecodes::_ireturn || + code[4] == Bytecodes::_areturn), "should do"); + u2 index = Bytes::get_native_u2(&code[2]); + + // Get the entry from the constant pool cache, and drop into + // the slow path if it has not been resolved + constantPoolCacheOop cache = method->constants()->cache(); + ConstantPoolCacheEntry* entry = cache->entry_at(index); + if (!entry->is_resolved(Bytecodes::_getfield)) { + normal_entry(method, 0, THREAD); + return; + } + + // Get the result and push it onto the stack + switch (entry->flag_state()) { + case ltos: + case dtos: + if (stack->available_words() < 1) { + Unimplemented(); + } + stack->alloc(wordSize); + break; + } + if (entry->is_volatile()) { + switch (entry->flag_state()) { + case ctos: + SET_LOCALS_INT(object->char_field_acquire(entry->f2()), 0); + break; + + case btos: + SET_LOCALS_INT(object->byte_field_acquire(entry->f2()), 0); + break; + + case stos: + SET_LOCALS_INT(object->short_field_acquire(entry->f2()), 0); + break; + + case itos: + SET_LOCALS_INT(object->int_field_acquire(entry->f2()), 0); + break; + + case ltos: + SET_LOCALS_LONG(object->long_field_acquire(entry->f2()), 0); + break; + + case ftos: + SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2()), 0); + break; + + case dtos: + SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2()), 0); + break; + + case atos: + SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2()), 0); + break; + + default: + ShouldNotReachHere(); + } + } + else { + switch (entry->flag_state()) { + case ctos: + SET_LOCALS_INT(object->char_field(entry->f2()), 0); + break; + + case btos: + SET_LOCALS_INT(object->byte_field(entry->f2()), 0); + break; + + case stos: + SET_LOCALS_INT(object->short_field(entry->f2()), 0); + break; + + case itos: + SET_LOCALS_INT(object->int_field(entry->f2()), 0); + break; + + case ltos: + SET_LOCALS_LONG(object->long_field(entry->f2()), 0); + break; + + case ftos: + SET_LOCALS_FLOAT(object->float_field(entry->f2()), 0); + break; + + case dtos: + SET_LOCALS_DOUBLE(object->double_field(entry->f2()), 0); + break; + + case atos: + SET_LOCALS_OBJECT(object->obj_field(entry->f2()), 0); + break; + + default: + ShouldNotReachHere(); + } + } +} + +void CppInterpreter::empty_entry(methodOop method, intptr_t UNUSED, TRAPS) { + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + + // Drop into the slow path if we need a safepoint check + if (SafepointSynchronize::do_call_back()) { + normal_entry(method, 0, THREAD); + return; + } + + // Pop our parameters + stack->set_sp(stack->sp() + method->size_of_parameters()); +} + +bool CppInterpreter::stack_overflow_imminent(JavaThread *thread) { + // How is the ABI stack? + address stack_top = thread->stack_base() - thread->stack_size(); + int free_stack = os::current_stack_pointer() - stack_top; + if (free_stack < StackShadowPages * os::vm_page_size()) { + return true; + } + + // How is the Zero stack? + // Throwing a StackOverflowError involves a VM call, which means + // we need a frame on the stack. We should be checking here to + // ensure that methods we call have enough room to install the + // largest possible frame, but that's more than twice the size + // of the entire Zero stack we get by default, so we just check + // we have *some* space instead... + free_stack = thread->zero_stack()->available_words() * wordSize; + if (free_stack < StackShadowPages * os::vm_page_size()) { + return true; + } + + return false; +} + +InterpreterFrame *InterpreterFrame::build(ZeroStack* stack, + const methodOop method, + JavaThread* thread) { + int monitor_words = + method->is_synchronized() ? frame::interpreter_frame_monitor_size() : 0; + int stack_words = method->is_native() ? 0 : method->max_stack(); + + if (header_words + monitor_words + stack_words > stack->available_words()) { + Unimplemented(); + } + + intptr_t *locals; + if (method->is_native()) + locals = stack->sp() + (method->size_of_parameters() - 1); + else + locals = stack->sp() + (method->max_locals() - 1); + + stack->push(0); // next_frame, filled in later + intptr_t *fp = stack->sp(); + assert(fp - stack->sp() == next_frame_off, "should be"); + + stack->push(INTERPRETER_FRAME); + assert(fp - stack->sp() == frame_type_off, "should be"); + + interpreterState istate = + (interpreterState) stack->alloc(sizeof(BytecodeInterpreter)); + assert(fp - stack->sp() == istate_off, "should be"); + + istate->set_locals(locals); + istate->set_method(method); + istate->set_self_link(istate); + istate->set_prev_link(NULL); + istate->set_thread(thread); + istate->set_bcp(method->is_native() ? NULL : method->code_base()); + istate->set_constants(method->constants()->cache()); + istate->set_msg(BytecodeInterpreter::method_entry); + istate->set_oop_temp(NULL); + istate->set_mdx(NULL); + istate->set_callee(NULL); + + istate->set_monitor_base((BasicObjectLock *) stack->sp()); + if (method->is_synchronized()) { + BasicObjectLock *monitor = + (BasicObjectLock *) stack->alloc(monitor_words * wordSize); + oop object; + if (method->is_static()) + object = method->constants()->pool_holder()->klass_part()->java_mirror(); + else + object = (oop) locals[0]; + monitor->set_obj(object); + } + + istate->set_stack_base(stack->sp()); + istate->set_stack(stack->sp() - 1); + if (stack_words) + stack->alloc(stack_words * wordSize); + istate->set_stack_limit(stack->sp() - 1); + + return (InterpreterFrame *) fp; +} + +int AbstractInterpreter::BasicType_as_index(BasicType type) { + int i = 0; + switch (type) { + case T_BOOLEAN: i = 0; break; + case T_CHAR : i = 1; break; + case T_BYTE : i = 2; break; + case T_SHORT : i = 3; break; + case T_INT : i = 4; break; + case T_LONG : i = 5; break; + case T_VOID : i = 6; break; + case T_FLOAT : i = 7; break; + case T_DOUBLE : i = 8; break; + case T_OBJECT : i = 9; break; + case T_ARRAY : i = 9; break; + default : ShouldNotReachHere(); + } + assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, + "index out of bounds"); + return i; +} + +address InterpreterGenerator::generate_empty_entry() { + if (!UseFastEmptyMethods) + return NULL; + + return generate_entry((address) CppInterpreter::empty_entry); +} + +address InterpreterGenerator::generate_accessor_entry() { + if (!UseFastAccessorMethods) + return NULL; + + return generate_entry((address) CppInterpreter::accessor_entry); +} + +address InterpreterGenerator::generate_native_entry(bool synchronized) { + assert(synchronized == false, "should be"); + + return generate_entry((address) CppInterpreter::native_entry); +} + +address InterpreterGenerator::generate_normal_entry(bool synchronized) { + assert(synchronized == false, "should be"); + + return generate_entry((address) CppInterpreter::normal_entry); +} + +address AbstractInterpreterGenerator::generate_method_entry( + AbstractInterpreter::MethodKind kind) { + address entry_point = NULL; + + switch (kind) { + case Interpreter::zerolocals: + case Interpreter::zerolocals_synchronized: + break; + + case Interpreter::native: + entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false); + break; + + case Interpreter::native_synchronized: + entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false); + break; + + case Interpreter::empty: + entry_point = ((InterpreterGenerator*) this)->generate_empty_entry(); + break; + + case Interpreter::accessor: + entry_point = ((InterpreterGenerator*) this)->generate_accessor_entry(); + break; + + case Interpreter::abstract: + entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry(); + break; + + case Interpreter::method_handle: + entry_point = ((InterpreterGenerator*) this)->generate_method_handle_entry(); + break; + + case Interpreter::java_lang_math_sin: + case Interpreter::java_lang_math_cos: + case Interpreter::java_lang_math_tan: + case Interpreter::java_lang_math_abs: + case Interpreter::java_lang_math_log: + case Interpreter::java_lang_math_log10: + case Interpreter::java_lang_math_sqrt: + entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind); + break; + + default: + ShouldNotReachHere(); + } + + if (entry_point == NULL) + entry_point = ((InterpreterGenerator*) this)->generate_normal_entry(false); + + return entry_point; +} + +InterpreterGenerator::InterpreterGenerator(StubQueue* code) + : CppInterpreterGenerator(code) { + generate_all(); +} + +// Deoptimization helpers + +InterpreterFrame *InterpreterFrame::build(ZeroStack* stack, int size) { + int size_in_words = size >> LogBytesPerWord; + assert(size_in_words * wordSize == size, "unaligned"); + assert(size_in_words >= header_words, "too small"); + + if (size_in_words > stack->available_words()) { + Unimplemented(); + } + + stack->push(0); // next_frame, filled in later + intptr_t *fp = stack->sp(); + assert(fp - stack->sp() == next_frame_off, "should be"); + + stack->push(INTERPRETER_FRAME); + assert(fp - stack->sp() == frame_type_off, "should be"); + + interpreterState istate = + (interpreterState) stack->alloc(sizeof(BytecodeInterpreter)); + assert(fp - stack->sp() == istate_off, "should be"); + istate->set_self_link(NULL); // mark invalid + + stack->alloc((size_in_words - header_words) * wordSize); + + return (InterpreterFrame *) fp; +} + +int AbstractInterpreter::layout_activation(methodOop method, + int tempcount, + int popframe_extra_args, + int moncount, + int callee_param_count, + int callee_locals, + frame* caller, + frame* interpreter_frame, + bool is_top_frame) { + assert(popframe_extra_args == 0, "what to do?"); + assert(!is_top_frame || (!callee_locals && !callee_param_count), + "top frame should have no caller") + + // This code must exactly match what InterpreterFrame::build + // does (the full InterpreterFrame::build, that is, not the + // one that creates empty frames for the deoptimizer). + // + // If interpreter_frame is not NULL then it will be filled in. + // It's size is determined by a previous call to this method, + // so it should be correct. + // + // Note that tempcount is the current size of the expression + // stack. For top most frames we will allocate a full sized + // expression stack and not the trimmed version that non-top + // frames have. + + int header_words = InterpreterFrame::header_words; + int monitor_words = moncount * frame::interpreter_frame_monitor_size(); + int stack_words = is_top_frame ? method->max_stack() : tempcount; + int callee_extra_locals = callee_locals - callee_param_count; + + if (interpreter_frame) { + intptr_t *locals = interpreter_frame->sp() + method->max_locals(); + interpreterState istate = interpreter_frame->get_interpreterState(); + intptr_t *monitor_base = (intptr_t*) istate; + intptr_t *stack_base = monitor_base - monitor_words; + intptr_t *stack = stack_base - tempcount - 1; + + BytecodeInterpreter::layout_interpreterState(istate, + caller, + NULL, + method, + locals, + stack, + stack_base, + monitor_base, + NULL, + is_top_frame); + } + return header_words + monitor_words + stack_words + callee_extra_locals; +} + +void BytecodeInterpreter::layout_interpreterState(interpreterState istate, + frame* caller, + frame* current, + methodOop method, + intptr_t* locals, + intptr_t* stack, + intptr_t* stack_base, + intptr_t* monitor_base, + intptr_t* frame_bottom, + bool is_top_frame) { + istate->set_locals(locals); + istate->set_method(method); + istate->set_self_link(istate); + istate->set_prev_link(NULL); + // thread will be set by a hacky repurposing of frame::patch_pc() + // bcp will be set by vframeArrayElement::unpack_on_stack() + istate->set_constants(method->constants()->cache()); + istate->set_msg(BytecodeInterpreter::method_resume); + istate->set_bcp_advance(0); + istate->set_oop_temp(NULL); + istate->set_mdx(NULL); + if (caller->is_interpreted_frame()) { + interpreterState prev = caller->get_interpreterState(); + prev->set_callee(method); + if (*prev->bcp() == Bytecodes::_invokeinterface) + prev->set_bcp_advance(5); + else + prev->set_bcp_advance(3); + } + istate->set_callee(NULL); + istate->set_monitor_base((BasicObjectLock *) monitor_base); + istate->set_stack_base(stack_base); + istate->set_stack(stack); + istate->set_stack_limit(stack_base - method->max_stack() - 1); +} + +address CppInterpreter::return_entry(TosState state, int length) { + ShouldNotCallThis(); +} + +address CppInterpreter::deopt_entry(TosState state, int length) { + return NULL; +} + +// Helper for (runtime) stack overflow checks + +int AbstractInterpreter::size_top_interpreter_activation(methodOop method) { + return 0; +} + +// Helper for figuring out if frames are interpreter frames + +bool CppInterpreter::contains(address pc) { +#ifdef PRODUCT + ShouldNotCallThis(); +#else + return false; // make frame::print_value_on work +#endif // !PRODUCT +} + +// Result handlers and convertors + +address CppInterpreterGenerator::generate_result_handler_for( + BasicType type) { + assembler()->advance(1); + return ShouldNotCallThisStub(); +} + +address CppInterpreterGenerator::generate_tosca_to_stack_converter( + BasicType type) { + assembler()->advance(1); + return ShouldNotCallThisStub(); +} + +address CppInterpreterGenerator::generate_stack_to_stack_converter( + BasicType type) { + assembler()->advance(1); + return ShouldNotCallThisStub(); +} + +address CppInterpreterGenerator::generate_stack_to_native_abi_converter( + BasicType type) { + assembler()->advance(1); + return ShouldNotCallThisStub(); +} + +#endif // CC_INTERP diff --git a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp new file mode 100644 index 00000000000..18b9891e937 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp @@ -0,0 +1,43 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + protected: + // Size of interpreter code + const static int InterpreterCodeSize = 6 * K; + + public: + // Method entries + static void normal_entry(methodOop method, intptr_t UNUSED, TRAPS); + static void native_entry(methodOop method, intptr_t UNUSED, TRAPS); + static void accessor_entry(methodOop method, intptr_t UNUSED, TRAPS); + static void empty_entry(methodOop method, intptr_t UNUSED, TRAPS); + + public: + // Main loop of normal_entry + static void main_loop(int recurse, TRAPS); + + private: + // Stack overflow checks + static bool stack_overflow_imminent(JavaThread *thread); diff --git a/hotspot/src/cpu/zero/vm/debug_zero.cpp b/hotspot/src/cpu/zero/vm/debug_zero.cpp new file mode 100644 index 00000000000..de6f077707a --- /dev/null +++ b/hotspot/src/cpu/zero/vm/debug_zero.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_debug_zero.cpp.incl" + +void pd_ps(frame f) { + ShouldNotCallThis(); +} diff --git a/hotspot/src/cpu/zero/vm/depChecker_zero.cpp b/hotspot/src/cpu/zero/vm/depChecker_zero.cpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/depChecker_zero.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/depChecker_zero.hpp b/hotspot/src/cpu/zero/vm/depChecker_zero.hpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/depChecker_zero.hpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/disassembler_zero.cpp b/hotspot/src/cpu/zero/vm/disassembler_zero.cpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/disassembler_zero.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/disassembler_zero.hpp b/hotspot/src/cpu/zero/vm/disassembler_zero.hpp new file mode 100644 index 00000000000..b4036c43d17 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/disassembler_zero.hpp @@ -0,0 +1,35 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// The disassembler prints out zero code annotated +// with Java specific information. + + static int pd_instruction_alignment() { + ShouldNotCallThis(); + } + + static const char* pd_cpu_opts() { + ShouldNotCallThis(); + } diff --git a/hotspot/src/cpu/zero/vm/dump_zero.cpp b/hotspot/src/cpu/zero/vm/dump_zero.cpp new file mode 100644 index 00000000000..648a081efc1 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/dump_zero.cpp @@ -0,0 +1,36 @@ +/* + * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_dump_zero.cpp.incl" + +void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list, + void** vtable, + char** md_top, + char* md_end, + char** mc_top, + char* mc_end) { + ShouldNotCallThis(); +} diff --git a/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp b/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp new file mode 100644 index 00000000000..03bd78102a4 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp @@ -0,0 +1,65 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// | ... | +// +--------------------+ ------------------ +// | parameter n-1 | low addresses +// | ... | +// | parameter 0 | +// | call_wrapper | +// | frame_type | +// | next_frame | high addresses +// +--------------------+ ------------------ +// | ... | + +class EntryFrame : public ZeroFrame { + private: + EntryFrame() : ZeroFrame() { + ShouldNotCallThis(); + } + + protected: + enum Layout { + call_wrapper_off = jf_header_words, + header_words + }; + + public: + static EntryFrame *build(ZeroStack* stack, + const intptr_t* parameters, + int parameter_words, + JavaCallWrapper* call_wrapper); + public: + JavaCallWrapper *call_wrapper() const { + return (JavaCallWrapper *) value_of_word(call_wrapper_off); + } + + public: + void identify_word(int frame_index, + int offset, + char* fieldbuf, + char* valuebuf, + int buflen) const; +}; diff --git a/hotspot/src/cpu/zero/vm/entry_zero.hpp b/hotspot/src/cpu/zero/vm/entry_zero.hpp new file mode 100644 index 00000000000..12f7e554b1a --- /dev/null +++ b/hotspot/src/cpu/zero/vm/entry_zero.hpp @@ -0,0 +1,64 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class ZeroEntry { + public: + ZeroEntry() { + ShouldNotCallThis(); + } + + private: + address _entry_point; + + public: + address entry_point() const { + return _entry_point; + } + void set_entry_point(address entry_point) { + _entry_point = entry_point; + } + + private: + typedef void (*NormalEntryFunc)(methodOop method, + intptr_t base_pc, + TRAPS); + typedef void (*OSREntryFunc)(methodOop method, + address osr_buf, + intptr_t base_pc, + TRAPS); + + public: + void invoke(methodOop method, TRAPS) const { + ((NormalEntryFunc) entry_point())(method, (intptr_t) this, THREAD); + } + void invoke_osr(methodOop method, address osr_buf, TRAPS) const { + ((OSREntryFunc) entry_point())(method, osr_buf, (intptr_t) this, THREAD); + } + + public: + static ByteSize entry_point_offset() { + return byte_offset_of(ZeroEntry, _entry_point); + } +}; diff --git a/hotspot/src/cpu/zero/vm/fakeStubFrame_zero.hpp b/hotspot/src/cpu/zero/vm/fakeStubFrame_zero.hpp new file mode 100644 index 00000000000..ec3054019ff --- /dev/null +++ b/hotspot/src/cpu/zero/vm/fakeStubFrame_zero.hpp @@ -0,0 +1,53 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// | ... | +// +--------------------+ ------------------ +// | frame_type | low addresses +// | next_frame | high addresses +// +--------------------+ ------------------ +// | ... | + +class FakeStubFrame : public ZeroFrame { + private: + FakeStubFrame() : ZeroFrame() { + ShouldNotCallThis(); + } + + protected: + enum Layout { + header_words = jf_header_words + }; + + public: + static FakeStubFrame *build(ZeroStack* stack); + + public: + void identify_word(int frame_index, + int offset, + char* fieldbuf, + char* valuebuf, + int buflen) const {} +}; diff --git a/hotspot/src/cpu/zero/vm/frame_zero.cpp b/hotspot/src/cpu/zero/vm/frame_zero.cpp new file mode 100644 index 00000000000..1b3cafdc589 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp @@ -0,0 +1,414 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_frame_zero.cpp.incl" + +#ifdef ASSERT +void RegisterMap::check_location_valid() { + ShouldNotCallThis(); +} +#endif + +bool frame::is_interpreted_frame() const { + return zeroframe()->is_interpreter_frame(); +} + +bool frame::is_fake_stub_frame() const { + return zeroframe()->is_fake_stub_frame(); +} + +frame frame::sender_for_entry_frame(RegisterMap *map) const { + assert(map != NULL, "map must be set"); + assert(!entry_frame_is_first(), "next Java fp must be non zero"); + assert(entry_frame_call_wrapper()->anchor()->last_Java_sp() == sender_sp(), + "sender should be next Java frame"); + map->clear(); + assert(map->include_argument_oops(), "should be set by clear"); + return frame(sender_sp(), sp() + 1); +} + +frame frame::sender_for_interpreter_frame(RegisterMap *map) const { + return frame(sender_sp(), sp() + 1); +} + +frame frame::sender_for_compiled_frame(RegisterMap *map) const { + return frame(sender_sp(), sp() + 1); +} + +frame frame::sender_for_fake_stub_frame(RegisterMap *map) const { + return frame(sender_sp(), sp() + 1); +} + +frame frame::sender(RegisterMap* map) const { + // Default is not to follow arguments; the various + // sender_for_xxx methods update this accordingly. + map->set_include_argument_oops(false); + + if (is_entry_frame()) + return sender_for_entry_frame(map); + + if (is_interpreted_frame()) + return sender_for_interpreter_frame(map); + + if (is_compiled_frame()) + return sender_for_compiled_frame(map); + + if (is_fake_stub_frame()) + return sender_for_fake_stub_frame(map); + + ShouldNotReachHere(); +} + +#ifdef CC_INTERP +BasicObjectLock* frame::interpreter_frame_monitor_begin() const { + return get_interpreterState()->monitor_base(); +} + +BasicObjectLock* frame::interpreter_frame_monitor_end() const { + return (BasicObjectLock*) get_interpreterState()->stack_base(); +} +#endif // CC_INTERP + +void frame::patch_pc(Thread* thread, address pc) { + // We borrow this call to set the thread pointer in the interpreter + // state; the hook to set up deoptimized frames isn't supplied it. + assert(pc == NULL, "should be"); + get_interpreterState()->set_thread((JavaThread *) thread); +} + +bool frame::safe_for_sender(JavaThread *thread) { + ShouldNotCallThis(); +} + +void frame::pd_gc_epilog() { +} + +bool frame::is_interpreted_frame_valid(JavaThread *thread) const { + ShouldNotCallThis(); +} + +BasicType frame::interpreter_frame_result(oop* oop_result, + jvalue* value_result) { + assert(is_interpreted_frame(), "interpreted frame expected"); + methodOop method = interpreter_frame_method(); + BasicType type = method->result_type(); + intptr_t* tos_addr = (intptr_t *) interpreter_frame_tos_address(); + oop obj; + + switch (type) { + case T_VOID: + break; + case T_BOOLEAN: + value_result->z = *(jboolean *) tos_addr; + break; + case T_BYTE: + value_result->b = *(jbyte *) tos_addr; + break; + case T_CHAR: + value_result->c = *(jchar *) tos_addr; + break; + case T_SHORT: + value_result->s = *(jshort *) tos_addr; + break; + case T_INT: + value_result->i = *(jint *) tos_addr; + break; + case T_LONG: + value_result->j = *(jlong *) tos_addr; + break; + case T_FLOAT: + value_result->f = *(jfloat *) tos_addr; + break; + case T_DOUBLE: + value_result->d = *(jdouble *) tos_addr; + break; + + case T_OBJECT: + case T_ARRAY: + if (method->is_native()) { + obj = get_interpreterState()->oop_temp(); + } + else { + oop* obj_p = (oop *) tos_addr; + obj = (obj_p == NULL) ? (oop) NULL : *obj_p; + } + assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check"); + *oop_result = obj; + break; + + default: + ShouldNotReachHere(); + } + + return type; +} + +int frame::frame_size(RegisterMap* map) const { +#ifdef PRODUCT + ShouldNotCallThis(); +#else + return 0; // make javaVFrame::print_value work +#endif // PRODUCT +} + +intptr_t* frame::interpreter_frame_tos_at(jint offset) const { + int index = (Interpreter::expr_offset_in_bytes(offset) / wordSize); + return &interpreter_frame_tos_address()[index]; +} + +void frame::zero_print_on_error(int frame_index, + outputStream* st, + char* buf, + int buflen) const { + // Divide the buffer between the field and the value + buflen >>= 1; + char *fieldbuf = buf; + char *valuebuf = buf + buflen; + + // Print each word of the frame + for (intptr_t *addr = fp(); addr <= sp(); addr++) { + int offset = sp() - addr; + + // Fill in default values, then try and improve them + snprintf(fieldbuf, buflen, "word[%d]", offset); + snprintf(valuebuf, buflen, PTR_FORMAT, *addr); + zeroframe()->identify_word(frame_index, offset, fieldbuf, valuebuf, buflen); + fieldbuf[buflen - 1] = '\0'; + valuebuf[buflen - 1] = '\0'; + + // Print the result + st->print_cr(" " PTR_FORMAT ": %-21s = %s", addr, fieldbuf, valuebuf); + } +} + +void ZeroFrame::identify_word(int frame_index, + int offset, + char* fieldbuf, + char* valuebuf, + int buflen) const { + switch (offset) { + case next_frame_off: + strncpy(fieldbuf, "next_frame", buflen); + break; + + case frame_type_off: + strncpy(fieldbuf, "frame_type", buflen); + if (is_entry_frame()) + strncpy(valuebuf, "ENTRY_FRAME", buflen); + else if (is_interpreter_frame()) + strncpy(valuebuf, "INTERPRETER_FRAME", buflen); + else if (is_shark_frame()) + strncpy(valuebuf, "SHARK_FRAME", buflen); + else if (is_fake_stub_frame()) + strncpy(valuebuf, "FAKE_STUB_FRAME", buflen); + break; + + default: + if (is_entry_frame()) { + as_entry_frame()->identify_word( + frame_index, offset, fieldbuf, valuebuf, buflen); + } + else if (is_interpreter_frame()) { + as_interpreter_frame()->identify_word( + frame_index, offset, fieldbuf, valuebuf, buflen); + } + else if (is_shark_frame()) { + as_shark_frame()->identify_word( + frame_index, offset, fieldbuf, valuebuf, buflen); + } + else if (is_fake_stub_frame()) { + as_fake_stub_frame()->identify_word( + frame_index, offset, fieldbuf, valuebuf, buflen); + } + } +} + +void EntryFrame::identify_word(int frame_index, + int offset, + char* fieldbuf, + char* valuebuf, + int buflen) const { + switch (offset) { + case call_wrapper_off: + strncpy(fieldbuf, "call_wrapper", buflen); + break; + + default: + snprintf(fieldbuf, buflen, "local[%d]", offset - 3); + } +} + +void InterpreterFrame::identify_word(int frame_index, + int offset, + char* fieldbuf, + char* valuebuf, + int buflen) const { + interpreterState istate = interpreter_state(); + bool is_valid = istate->self_link() == istate; + intptr_t *addr = addr_of_word(offset); + + // Fixed part + if (addr >= (intptr_t *) istate) { + const char *field = istate->name_of_field_at_address((address) addr); + if (field) { + if (is_valid && !strcmp(field, "_method")) { + istate->method()->name_and_sig_as_C_string(valuebuf, buflen); + } + else if (is_valid && !strcmp(field, "_bcp") && istate->bcp()) { + snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)", + (intptr_t) istate->bcp(), + istate->method()->bci_from(istate->bcp())); + } + snprintf(fieldbuf, buflen, "%sistate->%s", + field[strlen(field) - 1] == ')' ? "(": "", field); + } + else if (addr == (intptr_t *) istate) { + strncpy(fieldbuf, "(vtable for istate)", buflen); + } + return; + } + + // Variable part + if (!is_valid) + return; + + // JNI stuff + if (istate->method()->is_native() && addr < istate->stack_base()) { + address hA = istate->method()->signature_handler(); + if (hA != NULL) { + if (hA != (address) InterpreterRuntime::slow_signature_handler) { + InterpreterRuntime::SignatureHandler *handler = + InterpreterRuntime::SignatureHandler::from_handlerAddr(hA); + + intptr_t *params = istate->stack_base() - handler->argument_count(); + if (addr >= params) { + int param = addr - params; + const char *desc = ""; + if (param == 0) + desc = " (JNIEnv)"; + else if (param == 1) { + if (istate->method()->is_static()) + desc = " (mirror)"; + else + desc = " (this)"; + } + snprintf(fieldbuf, buflen, "parameter[%d]%s", param, desc); + return; + } + + for (int i = 0; i < handler->argument_count(); i++) { + if (params[i] == (intptr_t) addr) { + snprintf(fieldbuf, buflen, "unboxed parameter[%d]", i); + return; + } + } + } + } + return; + } + + // Monitors and stack + identify_vp_word(frame_index, addr, + (intptr_t *) istate->monitor_base(), + istate->stack_base(), + fieldbuf, buflen); +} + +void SharkFrame::identify_word(int frame_index, + int offset, + char* fieldbuf, + char* valuebuf, + int buflen) const { + // Fixed part + switch (offset) { + case pc_off: + strncpy(fieldbuf, "pc", buflen); + if (method()->is_oop()) { + nmethod *code = method()->code(); + if (code && code->pc_desc_at(pc())) { + SimpleScopeDesc ssd(code, pc()); + snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)", + (intptr_t) pc(), ssd.bci()); + } + } + return; + + case unextended_sp_off: + strncpy(fieldbuf, "unextended_sp", buflen); + return; + + case method_off: + strncpy(fieldbuf, "method", buflen); + if (method()->is_oop()) { + method()->name_and_sig_as_C_string(valuebuf, buflen); + } + return; + + case oop_tmp_off: + strncpy(fieldbuf, "oop_tmp", buflen); + return; + } + + // Variable part + if (method()->is_oop()) { + identify_vp_word(frame_index, addr_of_word(offset), + addr_of_word(header_words + 1), + unextended_sp() + method()->max_stack(), + fieldbuf, buflen); + } +} + +void ZeroFrame::identify_vp_word(int frame_index, + intptr_t* addr, + intptr_t* monitor_base, + intptr_t* stack_base, + char* fieldbuf, + int buflen) const { + // Monitors + if (addr >= stack_base && addr < monitor_base) { + int monitor_size = frame::interpreter_frame_monitor_size(); + int last_index = (monitor_base - stack_base) / monitor_size - 1; + int index = last_index - (addr - stack_base) / monitor_size; + intptr_t monitor = (intptr_t) ( + (BasicObjectLock *) monitor_base - 1 - index); + intptr_t offset = (intptr_t) addr - monitor; + + if (offset == BasicObjectLock::obj_offset_in_bytes()) + snprintf(fieldbuf, buflen, "monitor[%d]->_obj", index); + else if (offset == BasicObjectLock::lock_offset_in_bytes()) + snprintf(fieldbuf, buflen, "monitor[%d]->_lock", index); + + return; + } + + // Expression stack + if (addr < stack_base) { + snprintf(fieldbuf, buflen, "%s[%d]", + frame_index == 0 ? "stack_word" : "local", + (int) (stack_base - addr - 1)); + return; + } +} diff --git a/hotspot/src/cpu/zero/vm/frame_zero.hpp b/hotspot/src/cpu/zero/vm/frame_zero.hpp new file mode 100644 index 00000000000..81b6314571d --- /dev/null +++ b/hotspot/src/cpu/zero/vm/frame_zero.hpp @@ -0,0 +1,77 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// A frame represents a physical stack frame on the Zero stack. + + public: + enum { + pc_return_offset = 0 + }; + + // Constructor + public: + frame(intptr_t* sp, intptr_t* fp); + + // The sp of a Zero frame is the address of the highest word in + // that frame. We keep track of the lowest address too, so the + // boundaries of the frame are available for debug printing. + private: + intptr_t* _fp; + + public: + intptr_t* fp() const { + return _fp; + } + +#ifdef CC_INTERP + inline interpreterState get_interpreterState() const; +#endif // CC_INTERP + + public: + const ZeroFrame *zeroframe() const { + return (ZeroFrame *) sp(); + } + + const EntryFrame *zero_entryframe() const { + return zeroframe()->as_entry_frame(); + } + const InterpreterFrame *zero_interpreterframe() const { + return zeroframe()->as_interpreter_frame(); + } + const SharkFrame *zero_sharkframe() const { + return zeroframe()->as_shark_frame(); + } + + public: + bool is_fake_stub_frame() const; + + public: + frame sender_for_fake_stub_frame(RegisterMap* map) const; + + public: + void zero_print_on_error(int index, + outputStream* st, + char* buf, + int buflen) const; diff --git a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp new file mode 100644 index 00000000000..2751117f897 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp @@ -0,0 +1,151 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Constructors + +inline frame::frame() { + _sp = NULL; + _fp = NULL; + _pc = NULL; + _cb = NULL; + _deopt_state = unknown; +} + +inline frame::frame(intptr_t* sp, intptr_t* fp) { + _sp = sp; + _fp = fp; + switch (zeroframe()->type()) { + case ZeroFrame::ENTRY_FRAME: + _pc = StubRoutines::call_stub_return_pc(); + _cb = NULL; + break; + + case ZeroFrame::INTERPRETER_FRAME: + _pc = NULL; + _cb = NULL; + break; + + case ZeroFrame::SHARK_FRAME: + _pc = zero_sharkframe()->pc(); + _cb = CodeCache::find_blob_unsafe(pc()); + break; + + case ZeroFrame::FAKE_STUB_FRAME: + _pc = NULL; + _cb = NULL; + break; + + default: + ShouldNotReachHere(); + } + _deopt_state = not_deoptimized; +} + +// Accessors + +inline intptr_t* frame::sender_sp() const { + return (intptr_t *) zeroframe()->next(); +} + +inline intptr_t* frame::link() const { + ShouldNotCallThis(); +} + +#ifdef CC_INTERP +inline interpreterState frame::get_interpreterState() const { + return zero_interpreterframe()->interpreter_state(); +} + +inline intptr_t** frame::interpreter_frame_locals_addr() const { + return &(get_interpreterState()->_locals); +} + +inline intptr_t* frame::interpreter_frame_bcx_addr() const { + return (intptr_t*) &(get_interpreterState()->_bcp); +} + +inline constantPoolCacheOop* frame::interpreter_frame_cache_addr() const { + return &(get_interpreterState()->_constants); +} + +inline methodOop* frame::interpreter_frame_method_addr() const { + return &(get_interpreterState()->_method); +} + +inline intptr_t* frame::interpreter_frame_mdx_addr() const { + return (intptr_t*) &(get_interpreterState()->_mdx); +} + +inline intptr_t* frame::interpreter_frame_tos_address() const { + return get_interpreterState()->_stack + 1; +} +#endif // CC_INTERP + +inline int frame::interpreter_frame_monitor_size() { + return BasicObjectLock::size(); +} + +inline intptr_t* frame::interpreter_frame_expression_stack() const { + intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end(); + return monitor_end - 1; +} + +inline jint frame::interpreter_frame_expression_stack_direction() { + return -1; +} + +// Return a unique id for this frame. The id must have a value where +// we can distinguish identity and younger/older relationship. NULL +// represents an invalid (incomparable) frame. +inline intptr_t* frame::id() const { + return sp(); +} + +inline JavaCallWrapper* frame::entry_frame_call_wrapper() const { + return zero_entryframe()->call_wrapper(); +} + +inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) { + ShouldNotCallThis(); +} + +inline oop frame::saved_oop_result(RegisterMap* map) const { + ShouldNotCallThis(); +} + +inline bool frame::is_older(intptr_t* id) const { + ShouldNotCallThis(); +} + +inline intptr_t* frame::entry_frame_argument_at(int offset) const { + ShouldNotCallThis(); +} + +inline intptr_t* frame::unextended_sp() const { + if (zeroframe()->is_shark_frame()) + return zero_sharkframe()->unextended_sp(); + else + return (intptr_t *) -1; +} diff --git a/hotspot/src/cpu/zero/vm/globalDefinitions_zero.hpp b/hotspot/src/cpu/zero/vm/globalDefinitions_zero.hpp new file mode 100644 index 00000000000..90283f73762 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/globalDefinitions_zero.hpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include diff --git a/hotspot/src/cpu/zero/vm/globals_zero.hpp b/hotspot/src/cpu/zero/vm/globals_zero.hpp new file mode 100644 index 00000000000..89cf7077dee --- /dev/null +++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp @@ -0,0 +1,55 @@ +/* + * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// +// Set the default values for platform dependent flags used by the +// runtime system. See globals.hpp for details of what they do. +// + +define_pd_global(bool, ConvertSleepToYield, true); +define_pd_global(bool, ShareVtableStubs, true); +define_pd_global(bool, CountInterpCalls, true); +define_pd_global(bool, NeedsDeoptSuspend, false); + +define_pd_global(bool, ImplicitNullChecks, true); +define_pd_global(bool, UncommonNullCast, true); + +define_pd_global(intx, CodeEntryAlignment, 32); +define_pd_global(uintx, TLABSize, 0); +#ifdef _LP64 +define_pd_global(uintx, NewSize, ScaleForWordSize(2048 * K)); +#else +define_pd_global(uintx, NewSize, ScaleForWordSize(1024 * K)); +#endif // _LP64 +define_pd_global(intx, InlineFrequencyCount, 100); +define_pd_global(intx, InlineSmallCode, 1000); +define_pd_global(intx, PreInflateSpin, 10); + +define_pd_global(intx, StackYellowPages, 2); +define_pd_global(intx, StackRedPages, 1); +define_pd_global(intx, StackShadowPages, 3 LP64_ONLY(+3) DEBUG_ONLY(+3)); + +define_pd_global(bool, RewriteBytecodes, true); +define_pd_global(bool, RewriteFrequentPairs, true); diff --git a/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp b/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp new file mode 100644 index 00000000000..2a13793e937 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp @@ -0,0 +1,49 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_icBuffer_zero.cpp.incl" + +int InlineCacheBuffer::ic_stub_code_size() { + // NB set this once the functions below are implemented + return 4; +} + +void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin, + oop cached_oop, + address entry_point) { + // NB ic_stub_code_size() must return the size of the code we generate + ShouldNotCallThis(); +} + +address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) { + // NB ic_stub_code_size() must return the size of the code we generate + ShouldNotCallThis(); +} + +oop InlineCacheBuffer::ic_buffer_cached_oop(address code_begin) { + // NB ic_stub_code_size() must return the size of the code we generate + ShouldNotCallThis(); +} diff --git a/hotspot/src/cpu/zero/vm/icache_zero.cpp b/hotspot/src/cpu/zero/vm/icache_zero.cpp new file mode 100644 index 00000000000..2ec44595b6a --- /dev/null +++ b/hotspot/src/cpu/zero/vm/icache_zero.cpp @@ -0,0 +1,32 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_icache_zero.cpp.incl" + +void ICacheStubGenerator::generate_icache_flush( + ICache::flush_icache_stub_t* flush_icache_stub) { + ShouldNotCallThis(); +} diff --git a/hotspot/src/cpu/zero/vm/icache_zero.hpp b/hotspot/src/cpu/zero/vm/icache_zero.hpp new file mode 100644 index 00000000000..bd1f8a58556 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/icache_zero.hpp @@ -0,0 +1,36 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Interface for updating the instruction cache. Whenever the VM +// modifies code, part of the processor instruction cache potentially +// has to be flushed. This implementation is empty: Zero never deals +// with code, and LLVM handles cache flushing for Shark. + +class ICache : public AbstractICache { + public: + static void initialize() {} + static void invalidate_word(address addr) {} + static void invalidate_range(address start, int nbytes) {} +}; diff --git a/hotspot/src/cpu/zero/vm/interp_masm_zero.cpp b/hotspot/src/cpu/zero/vm/interp_masm_zero.cpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/interp_masm_zero.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/interp_masm_zero.hpp b/hotspot/src/cpu/zero/vm/interp_masm_zero.hpp new file mode 100644 index 00000000000..ee59ed22807 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/interp_masm_zero.hpp @@ -0,0 +1,38 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file specializes the assember with interpreter-specific macros + +class InterpreterMacroAssembler : public MacroAssembler { + public: + InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {} + + public: + RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, + Register tmp, + int offset) { + ShouldNotCallThis(); + } +}; diff --git a/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp b/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp new file mode 100644 index 00000000000..7c8199c05ce --- /dev/null +++ b/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp @@ -0,0 +1,75 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#ifdef CC_INTERP +// | ... | +// +--------------------+ ------------------ +// | stack slot n-1 | low addresses +// | ... | +// | stack slot 0 | +// | monitor 0 (maybe) | +// | ... | +// | interpreter state | +// | ... | +// | frame_type | +// | next_frame | high addresses +// +--------------------+ ------------------ +// | ... | + +class InterpreterFrame : public ZeroFrame { + friend class AbstractInterpreter; + + private: + InterpreterFrame() : ZeroFrame() { + ShouldNotCallThis(); + } + + protected: + enum Layout { + istate_off = jf_header_words + + (align_size_up_(sizeof(BytecodeInterpreter), + wordSize) >> LogBytesPerWord) - 1, + header_words + }; + + public: + static InterpreterFrame *build(ZeroStack* stack, + const methodOop method, + JavaThread* thread); + static InterpreterFrame *build(ZeroStack* stack, int size); + + public: + interpreterState interpreter_state() const { + return (interpreterState) addr_of_word(istate_off); + } + + public: + void identify_word(int frame_index, + int offset, + char* fieldbuf, + char* valuebuf, + int buflen) const; +}; +#endif // CC_INTERP diff --git a/hotspot/src/cpu/zero/vm/interpreterGenerator_zero.hpp b/hotspot/src/cpu/zero/vm/interpreterGenerator_zero.hpp new file mode 100644 index 00000000000..4158460e756 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/interpreterGenerator_zero.hpp @@ -0,0 +1,37 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + // Generation of Interpreter + // + friend class AbstractInterpreterGenerator; + + private: + address generate_normal_entry(bool synchronized); + address generate_native_entry(bool synchronized); + address generate_abstract_entry(); + address generate_math_entry(AbstractInterpreter::MethodKind kind); + address generate_empty_entry(); + address generate_accessor_entry(); + address generate_method_handle_entry(); diff --git a/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp b/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp new file mode 100644 index 00000000000..912a8aeacc7 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp @@ -0,0 +1,162 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_interpreterRT_zero.cpp.incl" + +void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_int() { + push(T_INT); + _cif->nargs++; +} + +void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_long() { + push(T_LONG); + _cif->nargs++; +} + +void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_float() { + push(T_FLOAT); + _cif->nargs++; +} + +void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_double() { + push(T_DOUBLE); + _cif->nargs++; +} + +void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_object() { + push(T_OBJECT); + _cif->nargs++; +} + +void InterpreterRuntime::SignatureHandlerGeneratorBase::push(BasicType type) { + ffi_type *ftype; + switch (type) { + case T_VOID: + ftype = &ffi_type_void; + break; + + case T_BOOLEAN: + ftype = &ffi_type_uint8; + break; + + case T_CHAR: + ftype = &ffi_type_uint16; + break; + + case T_BYTE: + ftype = &ffi_type_sint8; + break; + + case T_SHORT: + ftype = &ffi_type_sint16; + break; + + case T_INT: + ftype = &ffi_type_sint32; + break; + + case T_LONG: + ftype = &ffi_type_sint64; + break; + + case T_FLOAT: + ftype = &ffi_type_float; + break; + + case T_DOUBLE: + ftype = &ffi_type_double; + break; + + case T_OBJECT: + case T_ARRAY: + ftype = &ffi_type_pointer; + break; + + default: + ShouldNotReachHere(); + } + push((intptr_t) ftype); +} + +// For fast signature handlers the "signature handler" is generated +// into a temporary buffer. It is then copied to its final location, +// and pd_set_handler is called on it. We have this two stage thing +// to accomodate this. + +void InterpreterRuntime::SignatureHandlerGeneratorBase::generate( + uint64_t fingerprint) { + + // Build the argument types list + pass_object(); + if (method()->is_static()) + pass_object(); + iterate(fingerprint); + + // Tack on the result type + push(method()->result_type()); +} + +void InterpreterRuntime::SignatureHandler::finalize() { + ffi_status status = + ffi_prep_cif(cif(), + FFI_DEFAULT_ABI, + argument_count(), + result_type(), + argument_types()); + + assert(status == FFI_OK, "should be"); +} + +IRT_ENTRY(address, + InterpreterRuntime::slow_signature_handler(JavaThread* thread, + methodOop method, + intptr_t* unused1, + intptr_t* unused2)) + ZeroStack *stack = thread->zero_stack(); + + int required_words = + (align_size_up(sizeof(ffi_cif), wordSize) >> LogBytesPerWord) + + (method->is_static() ? 2 : 1) + method->size_of_parameters() + 1; + if (required_words > stack->available_words()) { + Unimplemented(); + } + + intptr_t *buf = (intptr_t *) stack->alloc(required_words * wordSize); + SlowSignatureHandlerGenerator sshg(methodHandle(thread, method), buf); + sshg.generate(UCONST64(-1)); + + SignatureHandler *handler = sshg.handler(); + handler->finalize(); + + return (address) handler; +IRT_END + +void SignatureHandlerLibrary::pd_set_handler(address handlerAddr) { + InterpreterRuntime::SignatureHandler *handler = + InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr); + + handler->finalize(); +} diff --git a/hotspot/src/cpu/zero/vm/interpreterRT_zero.hpp b/hotspot/src/cpu/zero/vm/interpreterRT_zero.hpp new file mode 100644 index 00000000000..4bc1034756d --- /dev/null +++ b/hotspot/src/cpu/zero/vm/interpreterRT_zero.hpp @@ -0,0 +1,127 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class SignatureHandler { + public: + static SignatureHandler *from_handlerAddr(address handlerAddr) { + return (SignatureHandler *) handlerAddr; + } + + public: + ffi_cif* cif() const { + return (ffi_cif *) this; + } + + int argument_count() const { + return cif()->nargs; + } + + ffi_type** argument_types() const { + return (ffi_type**) (cif() + 1); + } + + ffi_type* argument_type(int i) const { + return argument_types()[i]; + } + + ffi_type* result_type() const { + return *(argument_types() + argument_count()); + } + + protected: + friend class InterpreterRuntime; + friend class SignatureHandlerLibrary; + + void finalize(); +}; + +class SignatureHandlerGeneratorBase : public NativeSignatureIterator { + private: + ffi_cif* _cif; + + protected: + SignatureHandlerGeneratorBase(methodHandle method, ffi_cif *cif) + : NativeSignatureIterator(method), _cif(cif) { + _cif->nargs = 0; + } + + ffi_cif *cif() const { + return _cif; + } + + public: + void generate(uint64_t fingerprint); + + private: + void pass_int(); + void pass_long(); + void pass_float(); + void pass_double(); + void pass_object(); + + private: + void push(BasicType type); + virtual void push(intptr_t value) = 0; +}; + +class SignatureHandlerGenerator : public SignatureHandlerGeneratorBase { + private: + CodeBuffer* _cb; + + public: + SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) + : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->code_end()), + _cb(buffer) { + _cb->set_code_end((address) (cif() + 1)); + } + + private: + void push(intptr_t value) { + intptr_t *dst = (intptr_t *) _cb->code_end(); + _cb->set_code_end((address) (dst + 1)); + *dst = value; + } +}; + +class SlowSignatureHandlerGenerator : public SignatureHandlerGeneratorBase { + private: + intptr_t *_dst; + + public: + SlowSignatureHandlerGenerator(methodHandle method, intptr_t* buf) + : SignatureHandlerGeneratorBase(method, (ffi_cif *) buf) { + _dst = (intptr_t *) (cif() + 1); + } + + private: + void push(intptr_t value) { + *(_dst++) = value; + } + + public: + SignatureHandler *handler() const { + return (SignatureHandler *) cif(); + } +}; diff --git a/hotspot/src/cpu/zero/vm/interpreter_zero.cpp b/hotspot/src/cpu/zero/vm/interpreter_zero.cpp new file mode 100644 index 00000000000..1ece7bbdffe --- /dev/null +++ b/hotspot/src/cpu/zero/vm/interpreter_zero.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_interpreter_zero.cpp.incl" + +address AbstractInterpreterGenerator::generate_slow_signature_handler() { + _masm->advance(1); + return (address) InterpreterRuntime::slow_signature_handler; +} + +address InterpreterGenerator::generate_math_entry( + AbstractInterpreter::MethodKind kind) { + if (!InlineIntrinsics) + return NULL; + + Unimplemented(); +} + +address InterpreterGenerator::generate_abstract_entry() { + return ShouldNotCallThisEntry(); +} + +address InterpreterGenerator::generate_method_handle_entry() { + return ShouldNotCallThisEntry(); +} + +int AbstractInterpreter::size_activation(methodOop method, + int tempcount, + int popframe_extra_args, + int moncount, + int callee_param_count, + int callee_locals, + bool is_top_frame) { + return layout_activation(method, + tempcount, + popframe_extra_args, + moncount, + callee_param_count, + callee_locals, + (frame*) NULL, + (frame*) NULL, + is_top_frame); +} + +void Deoptimization::unwind_callee_save_values(frame* f, + vframeArray* vframe_array) { +} diff --git a/hotspot/src/cpu/zero/vm/interpreter_zero.hpp b/hotspot/src/cpu/zero/vm/interpreter_zero.hpp new file mode 100644 index 00000000000..67cac47d9a2 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/interpreter_zero.hpp @@ -0,0 +1,61 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + public: + static void invoke_method(methodOop method, address entry_point, TRAPS) { + ((ZeroEntry *) entry_point)->invoke(method, THREAD); + } + static void invoke_osr(methodOop method, + address entry_point, + address osr_buf, + TRAPS) { + ((ZeroEntry *) entry_point)->invoke_osr(method, osr_buf, THREAD); + } + + public: + static int expr_index_at(int i) { + return stackElementWords() * i; + } + static int expr_tag_index_at(int i) { + assert(TaggedStackInterpreter, "should not call this"); + Unimplemented(); + } + + static int expr_offset_in_bytes(int i) { + return stackElementSize() * i; + } + static int expr_tag_offset_in_bytes(int i) { + assert(TaggedStackInterpreter, "should not call this"); + Unimplemented(); + } + + static int local_index_at(int i) { + assert(i <= 0, "local direction already negated"); + return stackElementWords() * i + (value_offset_in_bytes() / wordSize); + } + static int local_tag_index_at(int i) { + assert(TaggedStackInterpreter, "should not call this"); + Unimplemented(); + } diff --git a/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp b/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp new file mode 100644 index 00000000000..e356cc91866 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp @@ -0,0 +1,72 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + public: + // Each arch must define reset, save, restore + // These are used by objects that only care about: + // 1 - initializing a new state (thread creation, javaCalls) + // 2 - saving a current state (javaCalls) + // 3 - restoring an old state (javaCalls) + + void clear() { + // clearing _last_Java_sp must be first + _last_Java_sp = NULL; + // fence? + _last_Java_pc = NULL; + } + + void copy(JavaFrameAnchor* src) { + // In order to make sure the transition state is valid for "this" + // We must clear _last_Java_sp before copying the rest of the new + // data + // + // Hack Alert: Temporary bugfix for 4717480/4721647 To act like + // previous version (pd_cache_state) don't NULL _last_Java_sp + // unless the value is changing + // + if (_last_Java_sp != src->_last_Java_sp) + _last_Java_sp = NULL; + + _last_Java_pc = src->_last_Java_pc; + // Must be last so profiler will always see valid frame if + // has_last_frame() is true + _last_Java_sp = src->_last_Java_sp; + } + + bool walkable() { + return true; + } + + void make_walkable(JavaThread* thread) { + // nothing to do + } + + intptr_t* last_Java_sp() const { + return _last_Java_sp; + } + + void set_last_Java_sp(intptr_t* sp) { + _last_Java_sp = sp; + } diff --git a/hotspot/src/cpu/zero/vm/jniFastGetField_zero.cpp b/hotspot/src/cpu/zero/vm/jniFastGetField_zero.cpp new file mode 100644 index 00000000000..251903426c9 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/jniFastGetField_zero.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_jniFastGetField_zero.cpp.incl" + +address JNI_FastGetField::generate_fast_get_boolean_field() { + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_byte_field() { + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_char_field() { + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_short_field() { + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_int_field() { + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_long_field() { + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_float_field() { + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_double_field() { + return (address) -1; +} diff --git a/hotspot/src/cpu/zero/vm/jniTypes_zero.hpp b/hotspot/src/cpu/zero/vm/jniTypes_zero.hpp new file mode 100644 index 00000000000..24f1aab092e --- /dev/null +++ b/hotspot/src/cpu/zero/vm/jniTypes_zero.hpp @@ -0,0 +1,108 @@ +/* + * Copyright 1998-2002 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file holds platform-dependent routines used to write primitive jni +// types to the array of arguments passed into JavaCalls::call + +class JNITypes : AllStatic { + // These functions write a java primitive type (in native format) + // to a java stack slot array to be passed as an argument to JavaCalls:calls. + // I.e., they are functionally 'push' operations if they have a 'pos' + // formal parameter. Note that jlong's and jdouble's are written + // _in reverse_ of the order in which they appear in the interpreter + // stack. This is because call stubs (see stubGenerator_zero.cpp) + // reverse the argument list constructed by JavaCallArguments (see + // javaCalls.hpp). + +private: + // Helper routines. + static inline void put_int2 (jint *from, jint *to) { to[0] = from[0]; to[1] = from[1]; } + static inline void put_int2 (jint *from, jint *to, int& pos) { put_int2 (from, (jint *)((intptr_t *)to + pos)); pos += 2; } + static inline void put_int2r(jint *from, jint *to) { to[0] = from[1]; to[1] = from[0]; } + static inline void put_int2r(jint *from, jint *to, int& pos) { put_int2r(from, (jint *)((intptr_t *)to + pos)); pos += 2; } + +public: + // Ints are stored in native format in one JavaCallArgument slot at *to. + static inline void put_int(jint from, intptr_t *to) { *(jint *)(to + 0 ) = from; } + static inline void put_int(jint from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = from; } + static inline void put_int(jint *from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = *from; } + +#ifdef _LP64 + // Longs are stored in native format in one JavaCallArgument slot at *(to+1). + static inline void put_long(jlong from, intptr_t *to) { *(jlong *)(to + 1 + 0) = from; } + static inline void put_long(jlong from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = from; pos += 2; } + static inline void put_long(jlong *from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = *from; pos += 2; } +#else + // Longs are stored in reversed native word format in two JavaCallArgument slots at *to. + // The high half is in *(to+1) and the low half in *to. + static inline void put_long(jlong from, intptr_t *to) { put_int2r((jint *)&from, (jint *)to); } + static inline void put_long(jlong from, intptr_t *to, int& pos) { put_int2r((jint *)&from, (jint *)to, pos); } + static inline void put_long(jlong *from, intptr_t *to, int& pos) { put_int2r((jint *) from, (jint *)to, pos); } +#endif + + // Oops are stored in native format in one JavaCallArgument slot at *to. + static inline void put_obj(oop from, intptr_t *to) { *(oop *)(to + 0 ) = from; } + static inline void put_obj(oop from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = from; } + static inline void put_obj(oop *from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = *from; } + + // Floats are stored in native format in one JavaCallArgument slot at *to. + static inline void put_float(jfloat from, intptr_t *to) { *(jfloat *)(to + 0 ) = from; } + static inline void put_float(jfloat from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = from; } + static inline void put_float(jfloat *from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = *from; } + +#ifdef _LP64 + // Doubles are stored in native word format in one JavaCallArgument slot at *(to+1). + static inline void put_double(jdouble from, intptr_t *to) { *(jdouble *)(to + 1 + 0) = from; } + static inline void put_double(jdouble from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = from; pos += 2; } + static inline void put_double(jdouble *from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = *from; pos += 2; } +#else + // Doubles are stored in reversed native word format in two JavaCallArgument slots at *to. + static inline void put_double(jdouble from, intptr_t *to) { put_int2r((jint *)&from, (jint *)to); } + static inline void put_double(jdouble from, intptr_t *to, int& pos) { put_int2r((jint *)&from, (jint *)to, pos); } + static inline void put_double(jdouble *from, intptr_t *to, int& pos) { put_int2r((jint *) from, (jint *)to, pos); } +#endif + + // The get_xxx routines, on the other hand, actually _do_ fetch + // java primitive types from the interpreter stack. + static inline jint get_int(intptr_t *from) { return *(jint *)from; } + +#ifdef _LP64 + static inline jlong get_long(intptr_t *from) { return *(jlong *)from; } +#else + static inline jlong get_long(intptr_t *from) { return ((jlong)(*( signed int *)((jint *)from )) << 32) | + ((jlong)(*(unsigned int *)((jint *)from + 1)) << 0); } +#endif + + static inline oop get_obj(intptr_t *from) { return *(oop *)from; } + static inline jfloat get_float(intptr_t *from) { return *(jfloat *)from; } + +#ifdef _LP64 + static inline jdouble get_double(intptr_t *from) { return *(jdouble *)from; } +#else + static inline jdouble get_double(intptr_t *from) { jlong jl = ((jlong)(*( signed int *)((jint *)from )) << 32) | + ((jlong)(*(unsigned int *)((jint *)from + 1)) << 0); + return *(jdouble *)&jl; } +#endif + +}; diff --git a/hotspot/src/cpu/zero/vm/jni_zero.h b/hotspot/src/cpu/zero/vm/jni_zero.h new file mode 100644 index 00000000000..40b52afbc52 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/jni_zero.h @@ -0,0 +1,38 @@ +/* + * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +#define JNIEXPORT +#define JNIIMPORT +#define JNICALL + +typedef int jint; +typedef signed char jbyte; + +#ifdef _LP64 +typedef long jlong; +#else +typedef long long jlong; +#endif diff --git a/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp b/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/nativeInst_zero.cpp b/hotspot/src/cpu/zero/vm/nativeInst_zero.cpp new file mode 100644 index 00000000000..0d4f10b4ec9 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/nativeInst_zero.cpp @@ -0,0 +1,50 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_nativeInst_zero.cpp.incl" + +// This method is called by nmethod::make_not_entrant_or_zombie to +// insert a jump to SharedRuntime::get_handle_wrong_method_stub() +// (dest) at the start of a compiled method (verified_entry) to avoid +// a race where a method is invoked while being made non-entrant. +// +// In Shark, verified_entry is a pointer to a SharkEntry. We can +// handle this simply by changing it's entry point to point at the +// interpreter. This only works because the interpreter and Shark +// calling conventions are the same. + +void NativeJump::patch_verified_entry(address entry, + address verified_entry, + address dest) { + assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "should be"); + +#ifdef CC_INTERP + ((ZeroEntry*) verified_entry)->set_entry_point( + (address) CppInterpreter::normal_entry); +#else + Unimplemented(); +#endif // CC_INTERP +} diff --git a/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp b/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp new file mode 100644 index 00000000000..3c650aa76c1 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp @@ -0,0 +1,185 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// We have interfaces for the following instructions: +// - NativeInstruction +// - - NativeCall +// - - NativeMovConstReg +// - - NativeMovConstRegPatching +// - - NativeJump +// - - NativeIllegalOpCode +// - - NativeReturn +// - - NativeReturnX (return with argument) +// - - NativePushConst +// - - NativeTstRegMem + +// The base class for different kinds of native instruction abstractions. +// Provides the primitive operations to manipulate code relative to this. + +class NativeInstruction VALUE_OBJ_CLASS_SPEC { + public: + bool is_jump() { + ShouldNotCallThis(); + } + + bool is_safepoint_poll() { + ShouldNotCallThis(); + } +}; + +inline NativeInstruction* nativeInstruction_at(address address) { + ShouldNotCallThis(); +} + +class NativeCall : public NativeInstruction { + public: + enum zero_specific_constants { + instruction_size = 0 // not used within the interpreter + }; + + address instruction_address() const { + ShouldNotCallThis(); + } + + address next_instruction_address() const { + ShouldNotCallThis(); + } + + address return_address() const { + ShouldNotCallThis(); + } + + address destination() const { + ShouldNotCallThis(); + } + + void set_destination_mt_safe(address dest) { + ShouldNotCallThis(); + } + + void verify_alignment() { + ShouldNotCallThis(); + } + + void verify() { + ShouldNotCallThis(); + } + + static bool is_call_before(address return_address) { + ShouldNotCallThis(); + } +}; + +inline NativeCall* nativeCall_before(address return_address) { + ShouldNotCallThis(); +} + +inline NativeCall* nativeCall_at(address address) { + ShouldNotCallThis(); +} + +class NativeMovConstReg : public NativeInstruction { + public: + address next_instruction_address() const { + ShouldNotCallThis(); + } + + intptr_t data() const { + ShouldNotCallThis(); + } + + void set_data(intptr_t x) { + ShouldNotCallThis(); + } +}; + +inline NativeMovConstReg* nativeMovConstReg_at(address address) { + ShouldNotCallThis(); +} + +class NativeMovRegMem : public NativeInstruction { + public: + int offset() const { + ShouldNotCallThis(); + } + + void set_offset(intptr_t x) { + ShouldNotCallThis(); + } + + void add_offset_in_bytes(int add_offset) { + ShouldNotCallThis(); + } +}; + +inline NativeMovRegMem* nativeMovRegMem_at(address address) { + ShouldNotCallThis(); +} + +class NativeJump : public NativeInstruction { + public: + enum zero_specific_constants { + instruction_size = 0 // not used within the interpreter + }; + + address jump_destination() const { + ShouldNotCallThis(); + } + + void set_jump_destination(address dest) { + ShouldNotCallThis(); + } + + static void check_verified_entry_alignment(address entry, + address verified_entry) { + } + + static void patch_verified_entry(address entry, + address verified_entry, + address dest); +}; + +inline NativeJump* nativeJump_at(address address) { + ShouldNotCallThis(); +} + +class NativeGeneralJump : public NativeInstruction { + public: + address jump_destination() const { + ShouldNotCallThis(); + } + + static void insert_unconditional(address code_pos, address entry) { + ShouldNotCallThis(); + } + + static void replace_mt_safe(address instr_addr, address code_buffer) { + ShouldNotCallThis(); + } +}; + +inline NativeGeneralJump* nativeGeneralJump_at(address address) { + ShouldNotCallThis(); +} diff --git a/hotspot/src/cpu/zero/vm/registerMap_zero.hpp b/hotspot/src/cpu/zero/vm/registerMap_zero.hpp new file mode 100644 index 00000000000..16a1de34bc7 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/registerMap_zero.hpp @@ -0,0 +1,39 @@ +/* + * Copyright 1998-2007 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + // machine-dependent implemention for register maps + friend class frame; + + private: + // This is the hook for finding a register in an "well-known" location, + // such as a register block of a predetermined format. + // Since there is none, we just return NULL. + // See registerMap_sparc.hpp for an example of grabbing registers + // from register save areas of a standard layout. + address pd_location(VMReg reg) const { return NULL; } + + // no PD state to clear or copy: + void pd_clear() {} + void pd_initialize() {} + void pd_initialize_from(const RegisterMap* map) {} diff --git a/hotspot/src/cpu/zero/vm/register_definitions_zero.cpp b/hotspot/src/cpu/zero/vm/register_definitions_zero.cpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/register_definitions_zero.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/register_zero.cpp b/hotspot/src/cpu/zero/vm/register_zero.cpp new file mode 100644 index 00000000000..a9590561fba --- /dev/null +++ b/hotspot/src/cpu/zero/vm/register_zero.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_register_zero.cpp.incl" + +const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers; +const int ConcreteRegisterImpl::max_fpr = + ConcreteRegisterImpl::max_gpr + FloatRegisterImpl::number_of_registers; + +const char* RegisterImpl::name() const { + ShouldNotCallThis(); +} + +const char* FloatRegisterImpl::name() const { + ShouldNotCallThis(); +} diff --git a/hotspot/src/cpu/zero/vm/register_zero.hpp b/hotspot/src/cpu/zero/vm/register_zero.hpp new file mode 100644 index 00000000000..abb7fc6ac8b --- /dev/null +++ b/hotspot/src/cpu/zero/vm/register_zero.hpp @@ -0,0 +1,110 @@ +/* + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class VMRegImpl; +typedef VMRegImpl* VMReg; + +// Use Register as shortcut +class RegisterImpl; +typedef RegisterImpl* Register; + +inline Register as_Register(int encoding) { + return (Register)(intptr_t) encoding; +} + +// The implementation of integer registers for the zero architecture +class RegisterImpl : public AbstractRegisterImpl { + public: + enum { + number_of_registers = 0 + }; + + // construction + inline friend Register as_Register(int encoding); + VMReg as_VMReg(); + + // derived registers, offsets, and addresses + Register successor() const { + return as_Register(encoding() + 1); + } + + // accessors + int encoding() const { + assert(is_valid(), "invalid register"); + return (intptr_t)this; + } + bool is_valid() const { + return 0 <= (intptr_t) this && (intptr_t)this < number_of_registers; + } + const char* name() const; +}; + +// Use FloatRegister as shortcut +class FloatRegisterImpl; +typedef FloatRegisterImpl* FloatRegister; + +inline FloatRegister as_FloatRegister(int encoding) { + return (FloatRegister)(intptr_t) encoding; +} + +// The implementation of floating point registers for the zero architecture +class FloatRegisterImpl : public AbstractRegisterImpl { + public: + enum { + number_of_registers = 0 + }; + + // construction + inline friend FloatRegister as_FloatRegister(int encoding); + VMReg as_VMReg(); + + // derived registers, offsets, and addresses + FloatRegister successor() const { + return as_FloatRegister(encoding() + 1); + } + + // accessors + int encoding() const { + assert(is_valid(), "invalid register"); + return (intptr_t)this; + } + bool is_valid() const { + return 0 <= (intptr_t) this && (intptr_t)this < number_of_registers; + } + const char* name() const; +}; + +class ConcreteRegisterImpl : public AbstractRegisterImpl { + public: + enum { + number_of_registers = RegisterImpl::number_of_registers + + FloatRegisterImpl::number_of_registers + }; + + static const int max_gpr; + static const int max_fpr; +}; + +CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1)); diff --git a/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp b/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp new file mode 100644 index 00000000000..64c6bff58e4 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_relocInfo_zero.cpp.incl" + +void Relocation::pd_set_data_value(address x, intptr_t o) { + ShouldNotCallThis(); +} + +address Relocation::pd_call_destination(address orig_addr) { + ShouldNotCallThis(); +} + +void Relocation::pd_set_call_destination(address x) { + ShouldNotCallThis(); +} + +address Relocation::pd_get_address_from_code() { + ShouldNotCallThis(); +} + +address* Relocation::pd_address_in_code() { + // Relocations in Shark are just stored directly + return (address *) addr(); +} + +int Relocation::pd_breakpoint_size() { + ShouldNotCallThis(); +} + +void Relocation::pd_swap_in_breakpoint(address x, + short* instrs, + int instrlen) { + ShouldNotCallThis(); +} + +void Relocation::pd_swap_out_breakpoint(address x, + short* instrs, + int instrlen) { + ShouldNotCallThis(); +} + +void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, + CodeBuffer* dst) { + ShouldNotCallThis(); +} + +void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, + CodeBuffer* dst) { + ShouldNotCallThis(); +} diff --git a/hotspot/src/cpu/zero/vm/relocInfo_zero.hpp b/hotspot/src/cpu/zero/vm/relocInfo_zero.hpp new file mode 100644 index 00000000000..afa47d041c4 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/relocInfo_zero.hpp @@ -0,0 +1,32 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + // machine-dependent parts of class relocInfo + private: + enum { + // these constants mean nothing without an assembler + offset_unit = 1, + format_width = 1 + }; diff --git a/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp new file mode 100644 index 00000000000..7bb4614980f --- /dev/null +++ b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp @@ -0,0 +1,108 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_sharedRuntime_zero.cpp.incl" + +DeoptimizationBlob *SharedRuntime::_deopt_blob; +SafepointBlob *SharedRuntime::_polling_page_safepoint_handler_blob; +SafepointBlob *SharedRuntime::_polling_page_return_handler_blob; +RuntimeStub *SharedRuntime::_wrong_method_blob; +RuntimeStub *SharedRuntime::_ic_miss_blob; +RuntimeStub *SharedRuntime::_resolve_opt_virtual_call_blob; +RuntimeStub *SharedRuntime::_resolve_virtual_call_blob; +RuntimeStub *SharedRuntime::_resolve_static_call_blob; + +int SharedRuntime::java_calling_convention(const BasicType *sig_bt, + VMRegPair *regs, + int total_args_passed, + int is_outgoing) { + return 0; +} + +AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters( + MacroAssembler *masm, + int total_args_passed, + int comp_args_on_stack, + const BasicType *sig_bt, + const VMRegPair *regs) { + return new AdapterHandlerEntry( + ShouldNotCallThisStub(), + ShouldNotCallThisStub(), + ShouldNotCallThisStub()); +} + +nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, + methodHandle method, + int total_in_args, + int comp_args_on_stack, + BasicType *in_sig_bt, + VMRegPair *in_regs, + BasicType ret_type) { + ShouldNotCallThis(); +} + +int Deoptimization::last_frame_adjust(int callee_parameters, + int callee_locals) { + return 0; +} + +uint SharedRuntime::out_preserve_stack_slots() { + ShouldNotCallThis(); +} + +static RuntimeStub* generate_empty_runtime_stub(const char* name) { + CodeBuffer buffer(name, 0, 0); + return RuntimeStub::new_runtime_stub(name, &buffer, 0, 0, NULL, false); +} + +static SafepointBlob* generate_empty_safepoint_blob() { + CodeBuffer buffer("handler_blob", 0, 0); + return SafepointBlob::create(&buffer, NULL, 0); +} + +void SharedRuntime::generate_stubs() { + _wrong_method_blob = + generate_empty_runtime_stub("wrong_method_stub"); + _ic_miss_blob = + generate_empty_runtime_stub("ic_miss_stub"); + _resolve_opt_virtual_call_blob = + generate_empty_runtime_stub("resolve_opt_virtual_call"); + _resolve_virtual_call_blob = + generate_empty_runtime_stub("resolve_virtual_call"); + _resolve_static_call_blob = + generate_empty_runtime_stub("resolve_static_call"); + + _polling_page_safepoint_handler_blob = + generate_empty_safepoint_blob(); + _polling_page_return_handler_blob = + generate_empty_safepoint_blob(); +} + +int SharedRuntime::c_calling_convention(const BasicType *sig_bt, + VMRegPair *regs, + int total_args_passed) { + ShouldNotCallThis(); +} diff --git a/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp b/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp new file mode 100644 index 00000000000..3337219a370 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp @@ -0,0 +1,79 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// | ... | +// +--------------------+ ------------------ +// | stack slot n-1 | low addresses +// | ... | +// | stack slot 0 | +// | monitor m-1 | +// | ... | +// | monitor 0 | +// | oop_tmp | +// | method | +// | unextended_sp | +// | pc | +// | frame_type | +// | next_frame | high addresses +// +--------------------+ ------------------ +// | ... | + +class SharkFrame : public ZeroFrame { + friend class SharkFunction; + + private: + SharkFrame() : ZeroFrame() { + ShouldNotCallThis(); + } + + protected: + enum Layout { + pc_off = jf_header_words, + unextended_sp_off, + method_off, + oop_tmp_off, + header_words + }; + + public: + address pc() const { + return (address) value_of_word(pc_off); + } + + intptr_t* unextended_sp() const { + return (intptr_t *) value_of_word(unextended_sp_off); + } + + methodOop method() const { + return (methodOop) value_of_word(method_off); + } + + public: + void identify_word(int frame_index, + int offset, + char* fieldbuf, + char* valuebuf, + int buflen) const; +}; diff --git a/hotspot/src/cpu/zero/vm/stack_zero.hpp b/hotspot/src/cpu/zero/vm/stack_zero.hpp new file mode 100644 index 00000000000..daf0b92099a --- /dev/null +++ b/hotspot/src/cpu/zero/vm/stack_zero.hpp @@ -0,0 +1,197 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class ZeroStack { + private: + intptr_t *_base; // the last available word + intptr_t *_top; // the word past the end of the stack + intptr_t *_sp; // the top word on the stack + + public: + ZeroStack() + : _base(NULL), _top(NULL), _sp(NULL) {} + + bool needs_setup() const { + return _base == NULL; + } + + void setup(void *mem, size_t size) { + assert(needs_setup(), "already set up"); + assert(!(size & WordAlignmentMask), "unaligned"); + + _base = (intptr_t *) mem; + _top = _base + (size >> LogBytesPerWord); + _sp = _top; + } + void teardown() { + assert(!needs_setup(), "not set up"); + assert(_sp == _top, "stuff on stack at teardown"); + + _base = NULL; + _top = NULL; + _sp = NULL; + } + + intptr_t *sp() const { + return _sp; + } + void set_sp(intptr_t *new_sp) { + assert(_top >= new_sp && new_sp >= _base, "bad stack pointer"); + _sp = new_sp; + } + + int available_words() const { + return _sp - _base; + } + + void push(intptr_t value) { + assert(_sp > _base, "stack overflow"); + *(--_sp) = value; + } + intptr_t pop() { + assert(_sp < _top, "stack underflow"); + return *(_sp++); + } + + void *alloc(size_t size) { + int count = align_size_up(size, wordSize) >> LogBytesPerWord; + assert(count <= available_words(), "stack overflow"); + return _sp -= count; + } + + public: + static ByteSize base_offset() { + return byte_offset_of(ZeroStack, _base); + } + static ByteSize top_offset() { + return byte_offset_of(ZeroStack, _top); + } + static ByteSize sp_offset() { + return byte_offset_of(ZeroStack, _sp); + } +}; + + +class EntryFrame; +class InterpreterFrame; +class SharkFrame; +class FakeStubFrame; + +// +// | ... | +// +--------------------+ ------------------ +// | ... | low addresses +// | frame_type | +// | next_frame | high addresses +// +--------------------+ ------------------ +// | ... | + +class ZeroFrame { + friend class frame; + friend class ZeroStackPrinter; + + protected: + ZeroFrame() { + ShouldNotCallThis(); + } + + enum Layout { + next_frame_off, + frame_type_off, + jf_header_words + }; + + enum FrameType { + ENTRY_FRAME = 1, + INTERPRETER_FRAME, + SHARK_FRAME, + FAKE_STUB_FRAME + }; + + protected: + intptr_t *addr_of_word(int offset) const { + return (intptr_t *) this - offset; + } + intptr_t value_of_word(int offset) const { + return *addr_of_word(offset); + } + + public: + ZeroFrame *next() const { + return (ZeroFrame *) value_of_word(next_frame_off); + } + + protected: + FrameType type() const { + return (FrameType) value_of_word(frame_type_off); + } + + public: + bool is_entry_frame() const { + return type() == ENTRY_FRAME; + } + bool is_interpreter_frame() const { + return type() == INTERPRETER_FRAME; + } + bool is_shark_frame() const { + return type() == SHARK_FRAME; + } + bool is_fake_stub_frame() const { + return type() == FAKE_STUB_FRAME; + } + + public: + EntryFrame *as_entry_frame() const { + assert(is_entry_frame(), "should be"); + return (EntryFrame *) this; + } + InterpreterFrame *as_interpreter_frame() const { + assert(is_interpreter_frame(), "should be"); + return (InterpreterFrame *) this; + } + SharkFrame *as_shark_frame() const { + assert(is_shark_frame(), "should be"); + return (SharkFrame *) this; + } + FakeStubFrame *as_fake_stub_frame() const { + assert(is_fake_stub_frame(), "should be"); + return (FakeStubFrame *) this; + } + + public: + void identify_word(int frame_index, + int offset, + char* fieldbuf, + char* valuebuf, + int buflen) const; + + protected: + void identify_vp_word(int frame_index, + intptr_t* addr, + intptr_t* monitor_base, + intptr_t* stack_base, + char* fieldbuf, + int buflen) const; +}; diff --git a/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp b/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp new file mode 100644 index 00000000000..b8ab9bb558a --- /dev/null +++ b/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp @@ -0,0 +1,251 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_stubGenerator_zero.cpp.incl" + +// Declaration and definition of StubGenerator (no .hpp file). +// For a more detailed description of the stub routine structure +// see the comment in stubRoutines.hpp + +class StubGenerator: public StubCodeGenerator { + private: + // The call stub is used to call Java from C + static void call_stub( + JavaCallWrapper *call_wrapper, + intptr_t* result, + BasicType result_type, + methodOop method, + address entry_point, + intptr_t* parameters, + int parameter_words, + TRAPS) { + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + + // Make sure we have no pending exceptions + assert(!HAS_PENDING_EXCEPTION, "call_stub called with pending exception"); + + // Set up the stack if necessary + bool stack_needs_teardown = false; + if (stack->needs_setup()) { + size_t stack_used = thread->stack_base() - (address) &stack_used; + size_t stack_free = thread->stack_size() - stack_used; + size_t zero_stack_size = align_size_down(stack_free / 2, wordSize); + + stack->setup(alloca(zero_stack_size), zero_stack_size); + stack_needs_teardown = true; + } + + // Allocate and initialize our frame + thread->push_zero_frame( + EntryFrame::build(stack, parameters, parameter_words, call_wrapper)); + + // Make the call + Interpreter::invoke_method(method, entry_point, THREAD); + + // Store result depending on type + if (!HAS_PENDING_EXCEPTION) { + switch (result_type) { + case T_INT: + *(jint *) result = *(jint *) stack->sp(); + break; + case T_LONG: + *(jlong *) result = *(jlong *) stack->sp(); + break; + case T_FLOAT: + *(jfloat *) result = *(jfloat *) stack->sp(); + break; + case T_DOUBLE: + *(jdouble *) result = *(jdouble *) stack->sp(); + break; + case T_OBJECT: + *(oop *) result = *(oop *) stack->sp(); + break; + default: + ShouldNotReachHere(); + } + } + + // Unwind our frame + thread->pop_zero_frame(); + + // Tear down the stack if necessary + if (stack_needs_teardown) + stack->teardown(); + } + + // These stubs get called from some dumb test routine. + // I'll write them properly when they're called from + // something that's actually doing something. + static void fake_arraycopy_stub(address src, address dst, int count) { + assert(count == 0, "huh?"); + } + + void generate_arraycopy_stubs() { + // Call the conjoint generation methods immediately after + // the disjoint ones so that short branches from the former + // to the latter can be generated. + StubRoutines::_jbyte_disjoint_arraycopy = (address) fake_arraycopy_stub; + StubRoutines::_jbyte_arraycopy = (address) fake_arraycopy_stub; + + StubRoutines::_jshort_disjoint_arraycopy = (address) fake_arraycopy_stub; + StubRoutines::_jshort_arraycopy = (address) fake_arraycopy_stub; + + StubRoutines::_jint_disjoint_arraycopy = (address) fake_arraycopy_stub; + StubRoutines::_jint_arraycopy = (address) fake_arraycopy_stub; + + StubRoutines::_jlong_disjoint_arraycopy = (address) fake_arraycopy_stub; + StubRoutines::_jlong_arraycopy = (address) fake_arraycopy_stub; + + StubRoutines::_oop_disjoint_arraycopy = ShouldNotCallThisStub(); + StubRoutines::_oop_arraycopy = ShouldNotCallThisStub(); + + StubRoutines::_checkcast_arraycopy = ShouldNotCallThisStub(); + StubRoutines::_unsafe_arraycopy = ShouldNotCallThisStub(); + StubRoutines::_generic_arraycopy = ShouldNotCallThisStub(); + + // We don't generate specialized code for HeapWord-aligned source + // arrays, so just use the code we've already generated + StubRoutines::_arrayof_jbyte_disjoint_arraycopy = + StubRoutines::_jbyte_disjoint_arraycopy; + StubRoutines::_arrayof_jbyte_arraycopy = + StubRoutines::_jbyte_arraycopy; + + StubRoutines::_arrayof_jshort_disjoint_arraycopy = + StubRoutines::_jshort_disjoint_arraycopy; + StubRoutines::_arrayof_jshort_arraycopy = + StubRoutines::_jshort_arraycopy; + + StubRoutines::_arrayof_jint_disjoint_arraycopy = + StubRoutines::_jint_disjoint_arraycopy; + StubRoutines::_arrayof_jint_arraycopy = + StubRoutines::_jint_arraycopy; + + StubRoutines::_arrayof_jlong_disjoint_arraycopy = + StubRoutines::_jlong_disjoint_arraycopy; + StubRoutines::_arrayof_jlong_arraycopy = + StubRoutines::_jlong_arraycopy; + + StubRoutines::_arrayof_oop_disjoint_arraycopy = + StubRoutines::_oop_disjoint_arraycopy; + StubRoutines::_arrayof_oop_arraycopy = + StubRoutines::_oop_arraycopy; + } + + void generate_initial() { + // Generates all stubs and initializes the entry points + + // entry points that exist in all platforms Note: This is code + // that could be shared among different platforms - however the + // benefit seems to be smaller than the disadvantage of having a + // much more complicated generator structure. See also comment in + // stubRoutines.hpp. + + StubRoutines::_forward_exception_entry = ShouldNotCallThisStub(); + StubRoutines::_call_stub_entry = (address) call_stub; + StubRoutines::_catch_exception_entry = ShouldNotCallThisStub(); + + // atomic calls + StubRoutines::_atomic_xchg_entry = ShouldNotCallThisStub(); + StubRoutines::_atomic_xchg_ptr_entry = ShouldNotCallThisStub(); + StubRoutines::_atomic_cmpxchg_entry = ShouldNotCallThisStub(); + StubRoutines::_atomic_cmpxchg_ptr_entry = ShouldNotCallThisStub(); + StubRoutines::_atomic_cmpxchg_long_entry = ShouldNotCallThisStub(); + StubRoutines::_atomic_add_entry = ShouldNotCallThisStub(); + StubRoutines::_atomic_add_ptr_entry = ShouldNotCallThisStub(); + StubRoutines::_fence_entry = ShouldNotCallThisStub(); + + // amd64 does this here, sparc does it in generate_all() + StubRoutines::_handler_for_unsafe_access_entry = + ShouldNotCallThisStub(); + } + + void generate_all() { + // Generates all stubs and initializes the entry points + + // These entry points require SharedInfo::stack0 to be set up in + // non-core builds and need to be relocatable, so they each + // fabricate a RuntimeStub internally. + StubRoutines::_throw_AbstractMethodError_entry = + ShouldNotCallThisStub(); + + StubRoutines::_throw_ArithmeticException_entry = + ShouldNotCallThisStub(); + + StubRoutines::_throw_NullPointerException_entry = + ShouldNotCallThisStub(); + + StubRoutines::_throw_NullPointerException_at_call_entry = + ShouldNotCallThisStub(); + + StubRoutines::_throw_StackOverflowError_entry = + ShouldNotCallThisStub(); + + // support for verify_oop (must happen after universe_init) + StubRoutines::_verify_oop_subroutine_entry = + ShouldNotCallThisStub(); + + // arraycopy stubs used by compilers + generate_arraycopy_stubs(); + } + + public: + StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) { + if (all) { + generate_all(); + } else { + generate_initial(); + } + } +}; + +void StubGenerator_generate(CodeBuffer* code, bool all) { + StubGenerator g(code, all); +} + +EntryFrame *EntryFrame::build(ZeroStack* stack, + const intptr_t* parameters, + int parameter_words, + JavaCallWrapper* call_wrapper) { + if (header_words + parameter_words > stack->available_words()) { + Unimplemented(); + } + + stack->push(0); // next_frame, filled in later + intptr_t *fp = stack->sp(); + assert(fp - stack->sp() == next_frame_off, "should be"); + + stack->push(ENTRY_FRAME); + assert(fp - stack->sp() == frame_type_off, "should be"); + + stack->push((intptr_t) call_wrapper); + assert(fp - stack->sp() == call_wrapper_off, "should be"); + + for (int i = 0; i < parameter_words; i++) + stack->push(parameters[i]); + + return (EntryFrame *) fp; +} diff --git a/hotspot/src/cpu/zero/vm/stubRoutines_zero.cpp b/hotspot/src/cpu/zero/vm/stubRoutines_zero.cpp new file mode 100644 index 00000000000..eb697aac8e8 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/stubRoutines_zero.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_stubRoutines_zero.cpp.incl" + +#ifdef IA32 +address StubRoutines::x86::_call_stub_compiled_return = NULL; +#endif // IA32 diff --git a/hotspot/src/cpu/zero/vm/stubRoutines_zero.hpp b/hotspot/src/cpu/zero/vm/stubRoutines_zero.hpp new file mode 100644 index 00000000000..31cff0eddef --- /dev/null +++ b/hotspot/src/cpu/zero/vm/stubRoutines_zero.hpp @@ -0,0 +1,51 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + // This file holds the platform specific parts of the StubRoutines + // definition. See stubRoutines.hpp for a description on how to + // extend it. + + public: + static address call_stub_return_pc() { + return (address) -1; + } + + static bool returns_to_call_stub(address return_pc) { + return return_pc == call_stub_return_pc(); + } + + enum platform_dependent_constants { + code_size1 = 0, // The assembler will fail with a guarantee + code_size2 = 0 // if these are too small. Simply increase + }; // them if that happens. + +#ifdef IA32 + class x86 { + friend class VMStructs; + + private: + static address _call_stub_compiled_return; + }; +#endif // IA32 diff --git a/hotspot/src/cpu/zero/vm/templateInterpreterGenerator_zero.hpp b/hotspot/src/cpu/zero/vm/templateInterpreterGenerator_zero.hpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/templateInterpreterGenerator_zero.hpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/templateInterpreter_zero.cpp b/hotspot/src/cpu/zero/vm/templateInterpreter_zero.cpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/templateInterpreter_zero.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/templateInterpreter_zero.hpp b/hotspot/src/cpu/zero/vm/templateInterpreter_zero.hpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/templateInterpreter_zero.hpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/templateTable_zero.cpp b/hotspot/src/cpu/zero/vm/templateTable_zero.cpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/templateTable_zero.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/templateTable_zero.hpp b/hotspot/src/cpu/zero/vm/templateTable_zero.hpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/templateTable_zero.hpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/vmStructs_zero.hpp b/hotspot/src/cpu/zero/vm/vmStructs_zero.hpp new file mode 100644 index 00000000000..565a9b5c5ab --- /dev/null +++ b/hotspot/src/cpu/zero/vm/vmStructs_zero.hpp @@ -0,0 +1,52 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// These are the CPU-specific fields, types and integer +// constants required by the Serviceability Agent. This file is +// referenced by vmStructs.cpp. + +#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs__.hpp's VM_STRUCTS_OS_CPU macro (and must */ + /* be present there) */ + +#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs__.hpp's VM_TYPES_OS_CPU macro (and must */ + /* be present there) */ + +#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs__.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */ + /* be present there) */ + +#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs__.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */ + /* be present there) */ diff --git a/hotspot/src/cpu/zero/vm/vm_version_zero.cpp b/hotspot/src/cpu/zero/vm/vm_version_zero.cpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/vm_version_zero.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/cpu/zero/vm/vm_version_zero.hpp b/hotspot/src/cpu/zero/vm/vm_version_zero.hpp new file mode 100644 index 00000000000..b971a8cc83b --- /dev/null +++ b/hotspot/src/cpu/zero/vm/vm_version_zero.hpp @@ -0,0 +1,31 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class VM_Version : public Abstract_VM_Version { + public: + static const char* cpu_features() { + return ""; + } +}; diff --git a/hotspot/src/cpu/zero/vm/vmreg_zero.cpp b/hotspot/src/cpu/zero/vm/vmreg_zero.cpp new file mode 100644 index 00000000000..6e5ea470ec4 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/vmreg_zero.cpp @@ -0,0 +1,62 @@ +/* + * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_vmreg_zero.cpp.incl" + +void VMRegImpl::set_regName() { + int i = 0; + Register reg = ::as_Register(0); + for ( ; i < ConcreteRegisterImpl::max_gpr ; ) { + regName[i++] = reg->name(); + reg = reg->successor(); + } + FloatRegister freg = ::as_FloatRegister(0); + for ( ; i < ConcreteRegisterImpl::max_fpr ; ) { + regName[i++] = freg->name(); + freg = freg->successor(); + } + assert(i == ConcreteRegisterImpl::number_of_registers, "fix this"); +} + +bool VMRegImpl::is_Register() { + return value() >= 0 && + value() < ConcreteRegisterImpl::max_gpr; +} + +bool VMRegImpl::is_FloatRegister() { + return value() >= ConcreteRegisterImpl::max_gpr && + value() < ConcreteRegisterImpl::max_fpr; +} + +Register VMRegImpl::as_Register() { + assert(is_Register(), "must be"); + return ::as_Register(value()); +} + +FloatRegister VMRegImpl::as_FloatRegister() { + assert(is_FloatRegister(), "must be" ); + return ::as_FloatRegister(value() - ConcreteRegisterImpl::max_gpr); +} diff --git a/hotspot/src/cpu/zero/vm/vmreg_zero.hpp b/hotspot/src/cpu/zero/vm/vmreg_zero.hpp new file mode 100644 index 00000000000..61c4a932b6a --- /dev/null +++ b/hotspot/src/cpu/zero/vm/vmreg_zero.hpp @@ -0,0 +1,29 @@ +/* + * Copyright 2006 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + bool is_Register(); + Register as_Register(); + + bool is_FloatRegister(); + FloatRegister as_FloatRegister(); diff --git a/hotspot/src/cpu/zero/vm/vmreg_zero.inline.hpp b/hotspot/src/cpu/zero/vm/vmreg_zero.inline.hpp new file mode 100644 index 00000000000..5bda84f9f09 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/vmreg_zero.inline.hpp @@ -0,0 +1,32 @@ +/* + * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +inline VMReg RegisterImpl::as_VMReg() { + return VMRegImpl::as_VMReg(encoding()); +} + +inline VMReg FloatRegisterImpl::as_VMReg() { + return VMRegImpl::as_VMReg(encoding() + ConcreteRegisterImpl::max_gpr); +} diff --git a/hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp b/hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp new file mode 100644 index 00000000000..57ccc9460b5 --- /dev/null +++ b/hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_vtableStubs_zero.cpp.incl" + +VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { + ShouldNotCallThis(); +} + +VtableStub* VtableStubs::create_itable_stub(int vtable_index) { + ShouldNotCallThis(); +} + +int VtableStub::pd_code_size_limit(bool is_vtable_stub) { + ShouldNotCallThis(); +} + +int VtableStub::pd_code_alignment() { + ShouldNotCallThis(); +} diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index eb510b66701..281e81c264f 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -176,7 +176,9 @@ bool os::have_special_privileges() { #endif // Cpu architecture string -#if defined(IA64) +#if defined(ZERO) +static char cpu_arch[] = ZERO_LIBARCH; +#elif defined(IA64) static char cpu_arch[] = "ia64"; #elif defined(IA32) static char cpu_arch[] = "i386"; @@ -1743,7 +1745,14 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"}, {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"}, - {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"} + {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}, + {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"}, + {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"}, + {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"}, + {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"}, + {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"}, + {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"}, + {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"} }; #if (defined IA32) @@ -1760,9 +1769,23 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) static Elf32_Half running_arch_code=EM_PPC64; #elif (defined __powerpc__) static Elf32_Half running_arch_code=EM_PPC; + #elif (defined ARM) + static Elf32_Half running_arch_code=EM_ARM; + #elif (defined S390) + static Elf32_Half running_arch_code=EM_S390; + #elif (defined ALPHA) + static Elf32_Half running_arch_code=EM_ALPHA; + #elif (defined MIPSEL) + static Elf32_Half running_arch_code=EM_MIPS_RS3_LE; + #elif (defined PARISC) + static Elf32_Half running_arch_code=EM_PARISC; + #elif (defined MIPS) + static Elf32_Half running_arch_code=EM_MIPS; + #elif (defined M68K) + static Elf32_Half running_arch_code=EM_68K; #else #error Method os::dll_load requires that one of following is defined:\ - IA32, AMD64, IA64, __sparc, __powerpc__ + IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K #endif // Identify compatability class for VM's architecture and library's architecture @@ -1794,10 +1817,12 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) return NULL; } +#ifndef S390 if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) { ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)"); return NULL; } +#endif // !S390 if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) { if ( lib_arch.name!=NULL ) { @@ -2586,7 +2611,9 @@ bool os::large_page_init() { // format has been changed), we'll use the largest page size supported by // the processor. +#ifndef ZERO _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M); +#endif // ZERO FILE *fp = fopen("/proc/meminfo", "r"); if (fp) { diff --git a/hotspot/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp b/hotspot/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp b/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp new file mode 100644 index 00000000000..ecd5b658775 --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp @@ -0,0 +1,293 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Implementation of class atomic + +#ifdef M68K + +/* + * __m68k_cmpxchg + * + * Atomically store newval in *ptr if *ptr is equal to oldval for user space. + * Returns newval on success and oldval if no exchange happened. + * This implementation is processor specific and works on + * 68020 68030 68040 and 68060. + * + * It will not work on ColdFire, 68000 and 68010 since they lack the CAS + * instruction. + * Using a kernelhelper would be better for arch complete implementation. + * + */ + +static inline int __m68k_cmpxchg(int oldval, int newval, volatile int *ptr) { + int ret; + __asm __volatile ("cas%.l %0,%2,%1" + : "=d" (ret), "+m" (*(ptr)) + : "d" (newval), "0" (oldval)); + return ret; +} + +/* Perform an atomic compare and swap: if the current value of `*PTR' + is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of + `*PTR' before the operation.*/ +static inline int m68k_compare_and_swap(volatile int *ptr, + int oldval, + int newval) { + for (;;) { + int prev = *ptr; + if (prev != oldval) + return prev; + + if (__m68k_cmpxchg (prev, newval, ptr) == newval) + // Success. + return prev; + + // We failed even though prev == oldval. Try again. + } +} + +/* Atomically add an int to memory. */ +static inline int m68k_add_and_fetch(volatile int *ptr, int add_value) { + for (;;) { + // Loop until success. + + int prev = *ptr; + + if (__m68k_cmpxchg (prev, prev + add_value, ptr) == prev + add_value) + return prev + add_value; + } +} + +/* Atomically write VALUE into `*PTR' and returns the previous + contents of `*PTR'. */ +static inline int m68k_lock_test_and_set(volatile int *ptr, int newval) { + for (;;) { + // Loop until success. + int prev = *ptr; + + if (__m68k_cmpxchg (prev, newval, ptr) == prev) + return prev; + } +} +#endif // M68K + +#ifdef ARM + +/* + * __kernel_cmpxchg + * + * Atomically store newval in *ptr if *ptr is equal to oldval for user space. + * Return zero if *ptr was changed or non-zero if no exchange happened. + * The C flag is also set if *ptr was changed to allow for assembly + * optimization in the calling code. + * + */ + +typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr); +#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0) + + + +/* Perform an atomic compare and swap: if the current value of `*PTR' + is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of + `*PTR' before the operation.*/ +static inline int arm_compare_and_swap(volatile int *ptr, + int oldval, + int newval) { + for (;;) { + int prev = *ptr; + if (prev != oldval) + return prev; + + if (__kernel_cmpxchg (prev, newval, ptr) == 0) + // Success. + return prev; + + // We failed even though prev == oldval. Try again. + } +} + +/* Atomically add an int to memory. */ +static inline int arm_add_and_fetch(volatile int *ptr, int add_value) { + for (;;) { + // Loop until a __kernel_cmpxchg succeeds. + + int prev = *ptr; + + if (__kernel_cmpxchg (prev, prev + add_value, ptr) == 0) + return prev + add_value; + } +} + +/* Atomically write VALUE into `*PTR' and returns the previous + contents of `*PTR'. */ +static inline int arm_lock_test_and_set(volatile int *ptr, int newval) { + for (;;) { + // Loop until a __kernel_cmpxchg succeeds. + int prev = *ptr; + + if (__kernel_cmpxchg (prev, newval, ptr) == 0) + return prev; + } +} +#endif // ARM + +inline void Atomic::store(jint store_value, volatile jint* dest) { + *dest = store_value; +} + +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { + *dest = store_value; +} + +inline jint Atomic::add(jint add_value, volatile jint* dest) { +#ifdef ARM + return arm_add_and_fetch(dest, add_value); +#else +#ifdef M68K + return m68k_add_and_fetch(dest, add_value); +#else + return __sync_add_and_fetch(dest, add_value); +#endif // M68K +#endif // ARM +} + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { +#ifdef ARM + return arm_add_and_fetch(dest, add_value); +#else +#ifdef M68K + return m68k_add_and_fetch(dest, add_value); +#else + return __sync_add_and_fetch(dest, add_value); +#endif // M68K +#endif // ARM +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void *) add_ptr(add_value, (volatile intptr_t *) dest); +} + +inline void Atomic::inc(volatile jint* dest) { + add(1, dest); +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) { + add_ptr(1, dest); +} + +inline void Atomic::inc_ptr(volatile void* dest) { + add_ptr(1, dest); +} + +inline void Atomic::dec(volatile jint* dest) { + add(-1, dest); +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) { + add_ptr(-1, dest); +} + +inline void Atomic::dec_ptr(volatile void* dest) { + add_ptr(-1, dest); +} + +inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) { +#ifdef ARM + return arm_lock_test_and_set(dest, exchange_value); +#else +#ifdef M68K + return m68k_lock_test_and_set(dest, exchange_value); +#else + // __sync_lock_test_and_set is a bizarrely named atomic exchange + // operation. Note that some platforms only support this with the + // limitation that the only valid value to store is the immediate + // constant 1. There is a test for this in JNI_CreateJavaVM(). + return __sync_lock_test_and_set (dest, exchange_value); +#endif // M68K +#endif // ARM +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, + volatile intptr_t* dest) { +#ifdef ARM + return arm_lock_test_and_set(dest, exchange_value); +#else +#ifdef M68K + return m68k_lock_test_and_set(dest, exchange_value); +#else + return __sync_lock_test_and_set (dest, exchange_value); +#endif // M68K +#endif // ARM +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void *) xchg_ptr((intptr_t) exchange_value, + (volatile intptr_t*) dest); +} + +inline jint Atomic::cmpxchg(jint exchange_value, + volatile jint* dest, + jint compare_value) { +#ifdef ARM + return arm_compare_and_swap(dest, compare_value, exchange_value); +#else +#ifdef M68K + return m68k_compare_and_swap(dest, compare_value, exchange_value); +#else + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); +#endif // M68K +#endif // ARM +} + +inline jlong Atomic::cmpxchg(jlong exchange_value, + volatile jlong* dest, + jlong compare_value) { + + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, + volatile intptr_t* dest, + intptr_t compare_value) { +#ifdef ARM + return arm_compare_and_swap(dest, compare_value, exchange_value); +#else +#ifdef M68K + return m68k_compare_and_swap(dest, compare_value, exchange_value); +#else + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); +#endif // M68K +#endif // ARM +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, + volatile void* dest, + void* compare_value) { + + return (void *) cmpxchg_ptr((intptr_t) exchange_value, + (volatile intptr_t*) dest, + (intptr_t) compare_value); +} diff --git a/hotspot/src/os_cpu/linux_zero/vm/bytes_linux_zero.inline.hpp b/hotspot/src/os_cpu/linux_zero/vm/bytes_linux_zero.inline.hpp new file mode 100644 index 00000000000..0f65dc3c111 --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/bytes_linux_zero.inline.hpp @@ -0,0 +1,40 @@ +/* + * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Efficient swapping of data bytes from Java byte +// ordering to native byte ordering and vice versa. + +#include + +inline u2 Bytes::swap_u2(u2 x) { + return bswap_16(x); +} + +inline u4 Bytes::swap_u4(u4 x) { + return bswap_32(x); +} + +inline u8 Bytes::swap_u8(u8 x) { + return bswap_64(x); +} diff --git a/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp b/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp new file mode 100644 index 00000000000..5c6587a0823 --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// +// Set the default values for platform dependent flags used by the +// runtime system. See globals.hpp for details of what they do. +// + +define_pd_global(bool, DontYieldALot, false); +#ifdef _LP64 +define_pd_global(intx, ThreadStackSize, 1536); +define_pd_global(intx, VMThreadStackSize, 1024); +#else +define_pd_global(intx, ThreadStackSize, 1024); +define_pd_global(intx, VMThreadStackSize, 512); +#endif // _LP64 +define_pd_global(intx, SurvivorRatio, 8); +define_pd_global(intx, CompilerThreadStackSize, 0); +define_pd_global(uintx, JVMInvokeMethodSlack, 8192); + +define_pd_global(bool, UseVectoredExceptions, false); +// Only used on 64 bit platforms +define_pd_global(uintx, HeapBaseMinAddress, 2*G); diff --git a/hotspot/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp b/hotspot/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp new file mode 100644 index 00000000000..b8970d0243d --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp @@ -0,0 +1,167 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#ifdef ARM + +/* + * ARM Kernel helper for memory barrier. + * Using __asm __volatile ("":::"memory") does not work reliable on ARM + * and gcc __sync_synchronize(); implementation does not use the kernel + * helper for all gcc versions so it is unreliable to use as well. + */ +typedef void (__kernel_dmb_t) (void); +#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0) + +#define FULL_MEM_BARRIER __kernel_dmb() +#define READ_MEM_BARRIER __kernel_dmb() +#define WRITE_MEM_BARRIER __kernel_dmb() + +#else // ARM + +#define FULL_MEM_BARRIER __sync_synchronize() + +#ifdef PPC + +#define READ_MEM_BARRIER __asm __volatile ("isync":::"memory") +#ifdef __NO_LWSYNC__ +#define WRITE_MEM_BARRIER __asm __volatile ("sync":::"memory") +#else +#define WRITE_MEM_BARRIER __asm __volatile ("lwsync":::"memory") +#endif + +#else // PPC + +#define READ_MEM_BARRIER __asm __volatile ("":::"memory") +#define WRITE_MEM_BARRIER __asm __volatile ("":::"memory") + +#endif // PPC + +#endif // ARM + + +inline void OrderAccess::loadload() { acquire(); } +inline void OrderAccess::storestore() { release(); } +inline void OrderAccess::loadstore() { acquire(); } +inline void OrderAccess::storeload() { fence(); } + +inline void OrderAccess::acquire() { + READ_MEM_BARRIER; +} + +inline void OrderAccess::release() { + WRITE_MEM_BARRIER; +} + +inline void OrderAccess::fence() { + FULL_MEM_BARRIER; +} + +inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { jbyte data = *p; acquire(); return data; } +inline jshort OrderAccess::load_acquire(volatile jshort* p) { jshort data = *p; acquire(); return data; } +inline jint OrderAccess::load_acquire(volatile jint* p) { jint data = *p; acquire(); return data; } +inline jlong OrderAccess::load_acquire(volatile jlong* p) { + jlong tmp; + os::atomic_copy64(p, &tmp); + acquire(); + return tmp; +} +inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { jubyte data = *p; acquire(); return data; } +inline jushort OrderAccess::load_acquire(volatile jushort* p) { jushort data = *p; acquire(); return data; } +inline juint OrderAccess::load_acquire(volatile juint* p) { juint data = *p; acquire(); return data; } +inline julong OrderAccess::load_acquire(volatile julong* p) { + julong tmp; + os::atomic_copy64(p, &tmp); + acquire(); + return tmp; +} +inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { jfloat data = *p; acquire(); return data; } +inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { + jdouble tmp; + os::atomic_copy64(p, &tmp); + acquire(); + return tmp; +} + +inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { + intptr_t data = *p; + acquire(); + return data; +} +inline void* OrderAccess::load_ptr_acquire(volatile void* p) { + void *data = *(void* volatile *)p; + acquire(); + return data; +} +inline void* OrderAccess::load_ptr_acquire(const volatile void* p) { + void *data = *(void* const volatile *)p; + acquire(); + return data; +} + +inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile jshort* p, jshort v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile jint* p, jint v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile jlong* p, jlong v) +{ release(); os::atomic_copy64(&v, p); } +inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile jushort* p, jushort v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile juint* p, juint v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile julong* p, julong v) +{ release(); os::atomic_copy64(&v, p); } +inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) +{ release(); os::atomic_copy64(&v, p); } + +inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { release(); *p = v; } +inline void OrderAccess::release_store_ptr(volatile void* p, void* v) +{ release(); *(void* volatile *)p = v; } + +inline void OrderAccess::store_fence(jbyte* p, jbyte v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jshort* p, jshort v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jint* p, jint v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jlong* p, jlong v) { os::atomic_copy64(&v, p); fence(); } +inline void OrderAccess::store_fence(jubyte* p, jubyte v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jushort* p, jushort v) { *p = v; fence(); } +inline void OrderAccess::store_fence(juint* p, juint v) { *p = v; fence(); } +inline void OrderAccess::store_fence(julong* p, julong v) { os::atomic_copy64(&v, p); fence(); } +inline void OrderAccess::store_fence(jfloat* p, jfloat v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jdouble* p, jdouble v) { os::atomic_copy64(&v, p); fence(); } + +inline void OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v) { *p = v; fence(); } +inline void OrderAccess::store_ptr_fence(void** p, void* v) { *p = v; fence(); } + +inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jint* p, jint v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store(p, v); fence(); } + +inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { release_store_ptr(p, v); fence(); } +inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) { release_store_ptr(p, v); fence(); } diff --git a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp new file mode 100644 index 00000000000..572702e7d6d --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp @@ -0,0 +1,456 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// do not include precompiled header file +#include "incls/_os_linux_zero.cpp.incl" + +address os::current_stack_pointer() { + address dummy = (address) &dummy; + return dummy; +} + +frame os::get_sender_for_C_frame(frame* fr) { + ShouldNotCallThis(); +} + +frame os::current_frame() { + // The only thing that calls this is the stack printing code in + // VMError::report: + // - Step 110 (printing stack bounds) uses the sp in the frame + // to determine the amount of free space on the stack. We + // set the sp to a close approximation of the real value in + // order to allow this step to complete. + // - Step 120 (printing native stack) tries to walk the stack. + // The frame we create has a NULL pc, which is ignored as an + // invalid frame. + frame dummy = frame(); + dummy.set_sp((intptr_t *) current_stack_pointer()); + return dummy; +} + +char* os::non_memory_address_word() { + // Must never look like an address returned by reserve_memory, + // even in its subfields (as defined by the CPU immediate fields, + // if the CPU splits constants across multiple instructions). +#ifdef SPARC + // On SPARC, 0 != %hi(any real address), because there is no + // allocation in the first 1Kb of the virtual address space. + return (char *) 0; +#else + // This is the value for x86; works pretty well for PPC too. + return (char *) -1; +#endif // SPARC +} + +void os::initialize_thread() { + // Nothing to do. +} + +address os::Linux::ucontext_get_pc(ucontext_t* uc) { + ShouldNotCallThis(); +} + +ExtendedPC os::fetch_frame_from_context(void* ucVoid, + intptr_t** ret_sp, + intptr_t** ret_fp) { + ShouldNotCallThis(); +} + +frame os::fetch_frame_from_context(void* ucVoid) { + ShouldNotCallThis(); +} + +extern "C" int +JVM_handle_linux_signal(int sig, + siginfo_t* info, + void* ucVoid, + int abort_if_unrecognized) { + ucontext_t* uc = (ucontext_t*) ucVoid; + + Thread* t = ThreadLocalStorage::get_thread_slow(); + + SignalHandlerMark shm(t); + + // Note: it's not uncommon that JNI code uses signal/sigset to + // install then restore certain signal handler (e.g. to temporarily + // block SIGPIPE, or have a SIGILL handler when detecting CPU + // type). When that happens, JVM_handle_linux_signal() might be + // invoked with junk info/ucVoid. To avoid unnecessary crash when + // libjsig is not preloaded, try handle signals that do not require + // siginfo/ucontext first. + + if (sig == SIGPIPE || sig == SIGXFSZ) { + // allow chained handler to go first + if (os::Linux::chained_handler(sig, info, ucVoid)) { + return true; + } else { + if (PrintMiscellaneous && (WizardMode || Verbose)) { + char buf[64]; + warning("Ignoring %s - see bugs 4229104 or 646499219", + os::exception_name(sig, buf, sizeof(buf))); + } + return true; + } + } + + JavaThread* thread = NULL; + VMThread* vmthread = NULL; + if (os::Linux::signal_handlers_are_installed) { + if (t != NULL ){ + if(t->is_Java_thread()) { + thread = (JavaThread*)t; + } + else if(t->is_VM_thread()){ + vmthread = (VMThread *)t; + } + } + } + + if (info != NULL && thread != NULL) { + // Handle ALL stack overflow variations here + if (sig == SIGSEGV) { + address addr = (address) info->si_addr; + + // check if fault address is within thread stack + if (addr < thread->stack_base() && + addr >= thread->stack_base() - thread->stack_size()) { + // stack overflow + if (thread->in_stack_yellow_zone(addr)) { + thread->disable_stack_yellow_zone(); + ShouldNotCallThis(); + } + else if (thread->in_stack_red_zone(addr)) { + thread->disable_stack_red_zone(); + ShouldNotCallThis(); + } + else { + // Accessing stack address below sp may cause SEGV if + // current thread has MAP_GROWSDOWN stack. This should + // only happen when current thread was created by user + // code with MAP_GROWSDOWN flag and then attached to VM. + // See notes in os_linux.cpp. + if (thread->osthread()->expanding_stack() == 0) { + thread->osthread()->set_expanding_stack(); + if (os::Linux::manually_expand_stack(thread, addr)) { + thread->osthread()->clear_expanding_stack(); + return true; + } + thread->osthread()->clear_expanding_stack(); + } + else { + fatal("recursive segv. expanding stack."); + } + } + } + } + + /*if (thread->thread_state() == _thread_in_Java) { + ShouldNotCallThis(); + } + else*/ if (thread->thread_state() == _thread_in_vm && + sig == SIGBUS && thread->doing_unsafe_access()) { + ShouldNotCallThis(); + } + + // jni_fast_GetField can trap at certain pc's if a GC + // kicks in and the heap gets shrunk before the field access. + /*if (sig == SIGSEGV || sig == SIGBUS) { + address addr = JNI_FastGetField::find_slowcase_pc(pc); + if (addr != (address)-1) { + stub = addr; + } + }*/ + + // Check to see if we caught the safepoint code in the process + // of write protecting the memory serialization page. It write + // enables the page immediately after protecting it so we can + // just return to retry the write. + if (sig == SIGSEGV && + os::is_memory_serialize_page(thread, (address) info->si_addr)) { + // Block current thread until permission is restored. + os::block_on_serialize_page_trap(); + return true; + } + } + + // signal-chaining + if (os::Linux::chained_handler(sig, info, ucVoid)) { + return true; + } + + if (!abort_if_unrecognized) { + // caller wants another chance, so give it to him + return false; + } + +#ifndef PRODUCT + if (sig == SIGSEGV) { + fatal("\n#" + "\n# /--------------------\\" + "\n# | segmentation fault |" + "\n# \\---\\ /--------------/" + "\n# /" + "\n# [-] |\\_/| " + "\n# (+)=C |o o|__ " + "\n# | | =-*-=__\\ " + "\n# OOO c_c_(___)"); + } +#endif // !PRODUCT + + const char *fmt = "caught unhandled signal %d"; + char buf[64]; + + sprintf(buf, fmt, sig); + fatal(buf); +} + +void os::Linux::init_thread_fpu_state(void) { + // Nothing to do +} + +int os::Linux::get_fpu_control_word() { + ShouldNotCallThis(); +} + +void os::Linux::set_fpu_control_word(int fpu) { + ShouldNotCallThis(); +} + +bool os::is_allocatable(size_t bytes) { + ShouldNotCallThis(); +} + +/////////////////////////////////////////////////////////////////////////////// +// thread stack + +size_t os::Linux::min_stack_allowed = 64 * K; + +bool os::Linux::supports_variable_stack_size() { + return true; +} + +size_t os::Linux::default_stack_size(os::ThreadType thr_type) { +#ifdef _LP64 + size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); +#else + size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K); +#endif // _LP64 + return s; +} + +size_t os::Linux::default_guard_size(os::ThreadType thr_type) { + // Only enable glibc guard pages for non-Java threads + // (Java threads have HotSpot guard pages) + return (thr_type == java_thread ? 0 : page_size()); +} + +static void current_stack_region(address *bottom, size_t *size) { + pthread_attr_t attr; + int res = pthread_getattr_np(pthread_self(), &attr); + if (res != 0) { + if (res == ENOMEM) { + vm_exit_out_of_memory(0, "pthread_getattr_np"); + } + else { + fatal1("pthread_getattr_np failed with errno = %d", res); + } + } + + address stack_bottom; + size_t stack_bytes; + res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes); + if (res != 0) { + fatal1("pthread_attr_getstack failed with errno = %d", res); + } + address stack_top = stack_bottom + stack_bytes; + + // The block of memory returned by pthread_attr_getstack() includes + // guard pages where present. We need to trim these off. + size_t page_bytes = os::Linux::page_size(); + assert(((intptr_t) stack_bottom & (page_bytes - 1)) == 0, "unaligned stack"); + + size_t guard_bytes; + res = pthread_attr_getguardsize(&attr, &guard_bytes); + if (res != 0) { + fatal1("pthread_attr_getguardsize failed with errno = %d", res); + } + int guard_pages = align_size_up(guard_bytes, page_bytes) / page_bytes; + assert(guard_bytes == guard_pages * page_bytes, "unaligned guard"); + +#ifdef IA64 + // IA64 has two stacks sharing the same area of memory, a normal + // stack growing downwards and a register stack growing upwards. + // Guard pages, if present, are in the centre. This code splits + // the stack in two even without guard pages, though in theory + // there's nothing to stop us allocating more to the normal stack + // or more to the register stack if one or the other were found + // to grow faster. + int total_pages = align_size_down(stack_bytes, page_bytes) / page_bytes; + stack_bottom += (total_pages - guard_pages) / 2 * page_bytes; +#endif // IA64 + + stack_bottom += guard_bytes; + + pthread_attr_destroy(&attr); + + // The initial thread has a growable stack, and the size reported + // by pthread_attr_getstack is the maximum size it could possibly + // be given what currently mapped. This can be huge, so we cap it. + if (os::Linux::is_initial_thread()) { + stack_bytes = stack_top - stack_bottom; + + if (stack_bytes > JavaThread::stack_size_at_create()) + stack_bytes = JavaThread::stack_size_at_create(); + + stack_bottom = stack_top - stack_bytes; + } + + assert(os::current_stack_pointer() >= stack_bottom, "should do"); + assert(os::current_stack_pointer() < stack_top, "should do"); + + *bottom = stack_bottom; + *size = stack_top - stack_bottom; +} + +address os::current_stack_base() { + address bottom; + size_t size; + current_stack_region(&bottom, &size); + return bottom + size; +} + +size_t os::current_stack_size() { + // stack size includes normal stack and HotSpot guard pages + address bottom; + size_t size; + current_stack_region(&bottom, &size); + return size; +} + +///////////////////////////////////////////////////////////////////////////// +// helper functions for fatal error handler + +void os::print_context(outputStream* st, void* context) { + ShouldNotCallThis(); +} + +///////////////////////////////////////////////////////////////////////////// +// Stubs for things that would be in linux_zero.s if it existed. +// You probably want to disassemble these monkeys to check they're ok. + +extern "C" { + int SpinPause() { + } + + int SafeFetch32(int *adr, int errValue) { + int value = errValue; + value = *adr; + return value; + } + intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) { + intptr_t value = errValue; + value = *adr; + return value; + } + + void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) { + if (from > to) { + jshort *end = from + count; + while (from < end) + *(to++) = *(from++); + } + else if (from < to) { + jshort *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + *(to--) = *(from--); + } + } + void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) { + if (from > to) { + jint *end = from + count; + while (from < end) + *(to++) = *(from++); + } + else if (from < to) { + jint *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + *(to--) = *(from--); + } + } + void _Copy_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) { + if (from > to) { + jlong *end = from + count; + while (from < end) + os::atomic_copy64(from++, to++); + } + else if (from < to) { + jlong *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + os::atomic_copy64(from--, to--); + } + } + + void _Copy_arrayof_conjoint_bytes(HeapWord* from, + HeapWord* to, + size_t count) { + ShouldNotCallThis(); + } + void _Copy_arrayof_conjoint_jshorts(HeapWord* from, + HeapWord* to, + size_t count) { + ShouldNotCallThis(); + } + void _Copy_arrayof_conjoint_jints(HeapWord* from, + HeapWord* to, + size_t count) { + ShouldNotCallThis(); + } + void _Copy_arrayof_conjoint_jlongs(HeapWord* from, + HeapWord* to, + size_t count) { + ShouldNotCallThis(); + } +}; + +///////////////////////////////////////////////////////////////////////////// +// Implementations of atomic operations not supported by processors. +// -- http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Atomic-Builtins.html + +#ifndef _LP64 +extern "C" { + long long unsigned int __sync_val_compare_and_swap_8( + volatile void *ptr, + long long unsigned int oldval, + long long unsigned int newval) { + ShouldNotCallThis(); + } +}; +#endif // !_LP64 diff --git a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp new file mode 100644 index 00000000000..d226d5ca726 --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp @@ -0,0 +1,45 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + static void setup_fpu() {} + + static bool is_allocatable(size_t bytes); + + // Used to register dynamic code cache area with the OS + // Note: Currently only used in 64 bit Windows implementations + static bool register_code_area(char *low, char *high) { return true; } + + // Atomically copy 64 bits of data + static void atomic_copy64(volatile void *src, volatile void *dst) { +#if defined(PPC) && !defined(_LP64) + double tmp; + asm volatile ("lfd %0, 0(%1)\n" + "stfd %0, 0(%2)\n" + : "=f"(tmp) + : "b"(src), "b"(dst)); +#else + *(jlong *) dst = *(jlong *) src; +#endif // PPC && !_LP64 + } diff --git a/hotspot/src/os_cpu/linux_zero/vm/prefetch_linux_zero.inline.hpp b/hotspot/src/os_cpu/linux_zero/vm/prefetch_linux_zero.inline.hpp new file mode 100644 index 00000000000..0e649c16ac8 --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/prefetch_linux_zero.inline.hpp @@ -0,0 +1,30 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +inline void Prefetch::read(void* loc, intx interval) { +} + +inline void Prefetch::write(void* loc, intx interval) { +} diff --git a/hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp b/hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp new file mode 100644 index 00000000000..efbc62c5700 --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_threadLS_linux_zero.cpp.incl" + +void ThreadLocalStorage::generate_code_for_get_thread() { + // nothing to do +} + +void ThreadLocalStorage::pd_init() { + // nothing to do +} + +void ThreadLocalStorage::pd_set_thread(Thread* thread) { + os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread); +} diff --git a/hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp b/hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp new file mode 100644 index 00000000000..de285ef83cc --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp @@ -0,0 +1,30 @@ +/* + * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Processor dependent parts of ThreadLocalStorage + + public: + static Thread* thread() { + return (Thread*) os::thread_local_storage_at(thread_index()); + } diff --git a/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp b/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp b/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp new file mode 100644 index 00000000000..a1ca908d08a --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp @@ -0,0 +1,104 @@ +/* + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + private: + ZeroStack _zero_stack; + ZeroFrame* _top_zero_frame; + + void pd_initialize() { + _top_zero_frame = NULL; + } + + public: + ZeroStack *zero_stack() { + return &_zero_stack; + } + + public: + ZeroFrame *top_zero_frame() { + return _top_zero_frame; + } + void push_zero_frame(ZeroFrame *frame) { + *(ZeroFrame **) frame = _top_zero_frame; + _top_zero_frame = frame; + } + void pop_zero_frame() { + zero_stack()->set_sp((intptr_t *) _top_zero_frame + 1); + _top_zero_frame = *(ZeroFrame **) _top_zero_frame; + } + + public: + static ByteSize zero_stack_offset() { + return byte_offset_of(JavaThread, _zero_stack); + } + static ByteSize top_zero_frame_offset() { + return byte_offset_of(JavaThread, _top_zero_frame); + } + + public: + void record_base_of_stack_pointer() { + assert(top_zero_frame() == NULL, "junk on stack prior to Java call"); + } + void set_base_of_stack_pointer(intptr_t* base_sp) { + assert(base_sp == NULL, "should be"); + assert(top_zero_frame() == NULL, "junk on stack after Java call"); + } + + public: + void set_last_Java_frame() { + JavaFrameAnchor *jfa = frame_anchor(); + jfa->set_last_Java_sp((intptr_t *) top_zero_frame()); + } + void reset_last_Java_frame() { + JavaFrameAnchor *jfa = frame_anchor(); + jfa->set_last_Java_sp(NULL); + } + + private: + frame pd_last_frame() { + assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); + return frame(last_Java_sp(), zero_stack()->sp()); + } + + public: + // Check for pending suspend requests and pending asynchronous + // exceptions. There are separate accessors for these, but + // _suspend_flags is volatile so using them would be unsafe. + bool has_special_condition_for_native_trans() { + return _suspend_flags != 0; + } + + public: + bool pd_get_top_frame_for_signal_handler(frame* fr_addr, + void* ucontext, + bool isInJava) { + ShouldNotCallThis(); + } + + // These routines are only used on cpu architectures that + // have separate register stacks (Itanium). + static bool register_stack_overflow() { return false; } + static void enable_register_stack_guard() {} + static void disable_register_stack_guard() {} diff --git a/hotspot/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp b/hotspot/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp new file mode 100644 index 00000000000..4c40bbf6de4 --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp @@ -0,0 +1,45 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// These are the OS and CPU-specific fields, types and integer +// constants required by the Serviceability Agent. This file is +// referenced by vmStructs.cpp. + +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry() + + +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry() + +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry() + +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry() diff --git a/hotspot/src/os_cpu/linux_zero/vm/vm_version_linux_zero.cpp b/hotspot/src/os_cpu/linux_zero/vm/vm_version_linux_zero.cpp new file mode 100644 index 00000000000..1fba6011651 --- /dev/null +++ b/hotspot/src/os_cpu/linux_zero/vm/vm_version_linux_zero.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty diff --git a/hotspot/src/share/vm/includeDB_zero b/hotspot/src/share/vm/includeDB_zero new file mode 100644 index 00000000000..4d1d52cfdf5 --- /dev/null +++ b/hotspot/src/share/vm/includeDB_zero @@ -0,0 +1,55 @@ +// +// Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved. +// Copyright 2009 Red Hat, Inc. +// 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +// CA 95054 USA or visit www.sun.com if you need additional information or +// have any questions. +// +// + +// NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps! + +entryFrame_.hpp javaCalls.hpp +entryFrame_.hpp stack_.hpp + +fakeStubFrame_.hpp stack_.hpp + +frame.hpp stack_.hpp + +frame.inline.hpp fakeStubFrame_.hpp +frame.inline.hpp entryFrame_.hpp +frame.inline.hpp interpreterFrame_.hpp +frame.inline.hpp sharkFrame_.hpp + +frame_.cpp interpreterRuntime.hpp +frame_.cpp scopeDesc.hpp + +interpreter.hpp entry_.hpp + +interpreterFrame_.hpp bytecodeInterpreter.hpp +interpreterFrame_.hpp methodOop.hpp +interpreterFrame_.hpp stack_.hpp +interpreterFrame_.hpp thread.hpp + +sharkFrame_.hpp methodOop.hpp +sharkFrame_.hpp stack_.hpp + +stack_.hpp sizes.hpp + +thread.hpp stack_.hpp diff --git a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp index e20ea9d1876..ac46f4ab5e1 100644 --- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp +++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp @@ -3031,9 +3031,9 @@ BytecodeInterpreter::print() { tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult); tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult); #endif -#ifdef IA64 +#if defined(IA64) && !defined(ZERO) tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp); -#endif // IA64 +#endif // IA64 && !ZERO tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link); } diff --git a/hotspot/src/share/vm/interpreter/oopMapCache.cpp b/hotspot/src/share/vm/interpreter/oopMapCache.cpp index 3b45b5956ec..170a73f9ce9 100644 --- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp +++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp @@ -281,7 +281,7 @@ class MaskFillerForNative: public NativeSignatureIterator { public: void pass_int() { /* ignore */ } void pass_long() { /* ignore */ } -#ifdef _LP64 +#if defined(_LP64) || defined(ZERO) void pass_float() { /* ignore */ } #endif void pass_double() { /* ignore */ } diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index b9e208f06b3..ccd568f3a6d 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1229,6 +1229,7 @@ void Arguments::set_ergonomics_flags() { } } +#ifndef ZERO #ifdef _LP64 // Check that UseCompressedOops can be set with the max heap size allocated // by ergonomics. @@ -1254,6 +1255,7 @@ void Arguments::set_ergonomics_flags() { // Also checks that certain machines are slower with compressed oops // in vm_version initialization code. #endif // _LP64 +#endif // !ZERO } void Arguments::set_parallel_gc_flags() { diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index f48cafe8208..df9cb2b778a 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -47,7 +47,6 @@ define_pd_global(intx, Tier4BackEdgeThreshold, 0); define_pd_global(intx, OnStackReplacePercentage, 0); define_pd_global(bool, ResizeTLAB, false); define_pd_global(intx, FreqInlineSize, 0); -define_pd_global(intx, InlineSmallCode, 0); define_pd_global(intx, NewSizeThreadIncrease, 4*K); define_pd_global(intx, NewRatio, 4); define_pd_global(intx, InlineClassNatives, true); diff --git a/hotspot/src/share/vm/runtime/jniHandles.hpp b/hotspot/src/share/vm/runtime/jniHandles.hpp index 99c4245028e..0cd24950caf 100644 --- a/hotspot/src/share/vm/runtime/jniHandles.hpp +++ b/hotspot/src/share/vm/runtime/jniHandles.hpp @@ -99,6 +99,8 @@ class JNIHandles : AllStatic { class JNIHandleBlock : public CHeapObj { friend class VMStructs; + friend class CppInterpreter; + private: enum SomeConstants { block_size_in_oops = 32 // Number of handles per handle block @@ -126,9 +128,11 @@ class JNIHandleBlock : public CHeapObj { // Fill block with bad_handle values void zap(); + protected: // No more handles in the both the current and following blocks void clear() { _top = 0; } + private: // Free list computation void rebuild_free_list(); diff --git a/hotspot/src/share/vm/runtime/mutex.hpp b/hotspot/src/share/vm/runtime/mutex.hpp index f0b9e8bd79d..dba1f23f5b4 100644 --- a/hotspot/src/share/vm/runtime/mutex.hpp +++ b/hotspot/src/share/vm/runtime/mutex.hpp @@ -61,18 +61,10 @@ union SplitWord { // full-word with separately addressable LSB } ; // Endian-ness ... index of least-significant byte in SplitWord.Bytes[] -#ifdef AMD64 // little +#ifdef VM_LITTLE_ENDIAN #define _LSBINDEX 0 #else -#if IA32 // little - #define _LSBINDEX 0 -#else -#ifdef SPARC // big #define _LSBINDEX (sizeof(intptr_t)-1) -#else - #error "unknown architecture" -#endif -#endif #endif class ParkEvent ; diff --git a/hotspot/src/share/vm/runtime/signature.hpp b/hotspot/src/share/vm/runtime/signature.hpp index 9b506d32902..9d67b0334ec 100644 --- a/hotspot/src/share/vm/runtime/signature.hpp +++ b/hotspot/src/share/vm/runtime/signature.hpp @@ -275,11 +275,14 @@ class NativeSignatureIterator: public SignatureIterator { void do_bool () { pass_int(); _jni_offset++; _offset++; } void do_char () { pass_int(); _jni_offset++; _offset++; } -#ifdef _LP64 +#if defined(_LP64) || defined(ZERO) void do_float () { pass_float(); _jni_offset++; _offset++; } - void do_double() { pass_double(); _jni_offset++; _offset += 2; } #else void do_float () { pass_int(); _jni_offset++; _offset++; } +#endif +#ifdef _LP64 + void do_double() { pass_double(); _jni_offset++; _offset += 2; } +#else void do_double() { pass_double(); _jni_offset += 2; _offset += 2; } #endif void do_byte () { pass_int(); _jni_offset++; _offset++; } @@ -303,8 +306,10 @@ class NativeSignatureIterator: public SignatureIterator { virtual void pass_int() = 0; virtual void pass_long() = 0; virtual void pass_object() = 0; -#ifdef _LP64 +#if defined(_LP64) || defined(ZERO) virtual void pass_float() = 0; +#endif +#ifdef _LP64 virtual void pass_double() = 0; #else virtual void pass_double() { pass_long(); } // may be same as long diff --git a/hotspot/src/share/vm/runtime/vm_version.cpp b/hotspot/src/share/vm/runtime/vm_version.cpp index b05e41ffc6b..39c08fc7fa1 100644 --- a/hotspot/src/share/vm/runtime/vm_version.cpp +++ b/hotspot/src/share/vm/runtime/vm_version.cpp @@ -93,9 +93,13 @@ void Abstract_VM_Version::initialize() { #else // KERNEL #ifdef TIERED #define VMTYPE "Server" -#else - #define VMTYPE COMPILER1_PRESENT("Client") \ - COMPILER2_PRESENT("Server") +#else // TIERED +#ifdef ZERO + #define VMTYPE "Zero" +#else // ZERO + #define VMTYPE COMPILER1_PRESENT("Client") \ + COMPILER2_PRESENT("Server") +#endif // ZERO #endif // TIERED #endif // KERNEL @@ -142,10 +146,14 @@ const char* Abstract_VM_Version::vm_release() { WINDOWS_ONLY("windows") \ SOLARIS_ONLY("solaris") +#ifdef ZERO +#define CPU ZERO_LIBARCH +#else #define CPU IA32_ONLY("x86") \ IA64_ONLY("ia64") \ AMD64_ONLY("amd64") \ SPARC_ONLY("sparc") +#endif // ZERO const char *Abstract_VM_Version::vm_platform_string() { return OS "-" CPU; diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp index f3f3edc12fc..2a2ddf83ab1 100644 --- a/hotspot/src/share/vm/utilities/vmError.cpp +++ b/hotspot/src/share/vm/utilities/vmError.cpp @@ -458,6 +458,40 @@ void VMError::report(outputStream* st) { if (_verbose && _thread && _thread->is_Java_thread()) { JavaThread* jt = (JavaThread*)_thread; +#ifdef ZERO + if (jt->zero_stack()->sp() && jt->top_zero_frame()) { + // StackFrameStream uses the frame anchor, which may not have + // been set up. This can be done at any time in Zero, however, + // so if it hasn't been set up then we just set it up now and + // clear it again when we're done. + bool has_last_Java_frame = jt->has_last_Java_frame(); + if (!has_last_Java_frame) + jt->set_last_Java_frame(); + st->print("Java frames:"); + + // If the top frame is a Shark frame and the frame anchor isn't + // set up then it's possible that the information in the frame + // is garbage: it could be from a previous decache, or it could + // simply have never been written. So we print a warning... + StackFrameStream sfs(jt); + if (!has_last_Java_frame && !sfs.is_done()) { + if (sfs.current()->zeroframe()->is_shark_frame()) { + st->print(" (TOP FRAME MAY BE JUNK)"); + } + } + st->cr(); + + // Print the frames + for(int i = 0; !sfs.is_done(); sfs.next(), i++) { + sfs.current()->zero_print_on_error(i, st, buf, sizeof(buf)); + st->cr(); + } + + // Reset the frame anchor if necessary + if (!has_last_Java_frame) + jt->reset_last_Java_frame(); + } +#else if (jt->has_last_Java_frame()) { st->print_cr("Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)"); for(StackFrameStream sfs(jt); !sfs.is_done(); sfs.next()) { @@ -465,6 +499,7 @@ void VMError::report(outputStream* st) { st->cr(); } } +#endif // ZERO } STEP(140, "(printing VM operation)" ) From 837c2b0a07c57235372057d0bde9c2ebe4fe6700 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 13 Oct 2009 14:02:53 -0700 Subject: [PATCH 038/172] 6887895: CONSTANT_Class_info getBaseName does not handle arrays of primitives correctly Reviewed-by: ksrini --- .../com/sun/tools/classfile/ConstantPool.java | 23 +++- .../test/tools/javap/classfile/T6887895.java | 121 ++++++++++++++++++ 2 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 langtools/test/tools/javap/classfile/T6887895.java diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java b/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java index ba53f2d2a24..7ceac568728 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java @@ -369,14 +369,33 @@ public class ConstantPool { return 3; } + /** + * Get the raw value of the class referenced by this constant pool entry. + * This will either be the name of the class, in internal form, or a + * descriptor for an array class. + * @return the raw value of the class + */ public String getName() throws ConstantPoolException { return cp.getUTF8Value(name_index); } + /** + * If this constant pool entry identifies either a class or interface type, + * or a possibly multi-dimensional array of a class of interface type, + * return the name of the class or interface in internal form. Otherwise, + * (i.e. if this is a possibly multi-dimensional array of a primitive type), + * return null. + * @return the base class or interface name + */ public String getBaseName() throws ConstantPoolException { String name = getName(); - int index = name.indexOf("[L") + 1; - return name.substring(index); + if (name.startsWith("[")) { + int index = name.indexOf("[L"); + if (index == -1) + return null; + return name.substring(index + 2, name.length() - 1); + } else + return name; } public int getDimensionCount() throws ConstantPoolException { diff --git a/langtools/test/tools/javap/classfile/T6887895.java b/langtools/test/tools/javap/classfile/T6887895.java new file mode 100644 index 00000000000..a81ac9d40d9 --- /dev/null +++ b/langtools/test/tools/javap/classfile/T6887895.java @@ -0,0 +1,121 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6887895 + * @summary CONSTANT_Class_info getBaseName does not handle arrays of primitives correctly + */ + +import java.io.*; +import java.net.*; +import java.util.*; +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.ConstantPool.*; + +public class T6887895 { + public static void main(String[] args) throws Exception { + new T6887895().run(); + } + + void run() throws Exception { + Set found = new TreeSet(); + + ClassFile cf = getClassFile("T6887895$Test.class"); + for (CPInfo cpInfo: cf.constant_pool.entries()) { + if (cpInfo instanceof CONSTANT_Class_info) { + CONSTANT_Class_info info = (CONSTANT_Class_info) cpInfo; + String name = info.getName(); + String baseName = info.getBaseName(); + System.out.println("found: " + name + " " + baseName); + if (baseName != null) + found.add(baseName); + } + } + + String[] expectNames = { + "java/lang/Object", + "java/lang/String", + "T6887895", + "T6887895$Test" + }; + + Set expect = new TreeSet(Arrays.asList(expectNames)); + if (!found.equals(expect)) { + System.err.println("found: " + found); + System.err.println("expect: " + expect); + throw new Exception("unexpected values found"); + } + } + + ClassFile getClassFile(String name) throws IOException, ConstantPoolException { + URL url = getClass().getResource(name); + InputStream in = url.openStream(); + try { + return ClassFile.read(in); + } finally { + in.close(); + } + } + + class Test { + void m() { + boolean[] az = new boolean[0]; + boolean[][] aaz = new boolean[0][]; + boolean[][][] aaaz = new boolean[0][][]; + + byte[] ab = new byte[0]; + byte[][] aab = new byte[0][]; + byte[][][] aaab = new byte[0][][]; + + char[] ac = new char[0]; + char[][] aac = new char[0][]; + char[][][] aaac = new char[0][][]; + + double[] ad = new double[0]; + double[][] aad = new double[0][]; + double[][][] aaad = new double[0][][]; + + float[] af = new float[0]; + float[][] aaf = new float[0][]; + float[][][] aaaf = new float[0][][]; + + int[] ai = new int[0]; + int[][] aai = new int[0][]; + int[][][] aaai = new int[0][][]; + + long[] al = new long[0]; + long[][] aal = new long[0][]; + long[][][] aaal = new long[0][][]; + + short[] as = new short[0]; + short[][] aas = new short[0][]; + short[][][] aaas = new short[0][][]; + + String[] aS = new String[0]; + String[][] aaS = new String[0][]; + String[][][] aaaS = new String[0][][]; + } + } +} + From 8b993775d5b32f28886d3cc06a7f8977ccd54609 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 13 Oct 2009 14:08:57 -0700 Subject: [PATCH 039/172] 6648344: (reflect spec) State default of isAccessible for reflective objects Reviewed-by: alanb --- .../java/lang/reflect/AccessibleObject.java | 2 + .../lang/reflect/DefaultAccessibility.java | 69 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 jdk/test/java/lang/reflect/DefaultAccessibility.java diff --git a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java index 1f94a4c5a15..a48f6b19867 100644 --- a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java +++ b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java @@ -44,6 +44,8 @@ import java.lang.annotation.Annotation; * as Java Object Serialization or other persistence mechanisms, to * manipulate objects in a manner that would normally be prohibited. * + *

By default, a reflected object is not accessible. + * * @see Field * @see Method * @see Constructor diff --git a/jdk/test/java/lang/reflect/DefaultAccessibility.java b/jdk/test/java/lang/reflect/DefaultAccessibility.java new file mode 100644 index 00000000000..0f74d044ef6 --- /dev/null +++ b/jdk/test/java/lang/reflect/DefaultAccessibility.java @@ -0,0 +1,69 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6648344 + * @summary Test that default accessibility is false + * @author Joseph D. Darcy + */ + +import java.lang.reflect.*; + +public class DefaultAccessibility { + private DefaultAccessibility() { + super(); + } + + private static int f = 42; + + public static void main(String... args) throws Exception { + Class daClass = (new DefaultAccessibility()).getClass(); + + int elementCount = 0; + for(Constructor ctor : daClass.getDeclaredConstructors()) { + elementCount++; + if (ctor.isAccessible()) + throw new RuntimeException("Unexpected accessibility for constructor " + + ctor); + } + + for(Method method : daClass.getDeclaredMethods()) { + elementCount++; + if (method.isAccessible()) + throw new RuntimeException("Unexpected accessibility for method " + + method); + } + + for(Field field : daClass.getDeclaredFields()) { + elementCount++; + if (field.isAccessible()) + throw new RuntimeException("Unexpected accessibility for field " + + field); + } + + if (elementCount < 3) + throw new RuntimeException("Expected at least three members; only found " + + elementCount); + } +} From 51a7e386003e320958ea9eb187f1f1f450d74afc Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 13 Oct 2009 15:26:30 -0700 Subject: [PATCH 040/172] 6891079: Compiler allows invalid binary literals 0b and oBL Reviewed-by: darcy --- .../classes/com/sun/tools/javac/parser/Scanner.java | 6 +++++- .../sun/tools/javac/resources/compiler.properties | 2 ++ langtools/test/tools/javac/literals/T6891079.java | 12 ++++++++++++ langtools/test/tools/javac/literals/T6891079.out | 7 +++++++ 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/literals/T6891079.java create mode 100644 langtools/test/tools/javac/literals/T6891079.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java index 6ed9cdc2538..287b7e8c901 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java @@ -876,7 +876,11 @@ public class Scanner implements Lexer { } scanChar(); skipIllegalUnderscores(); - scanNumber(2); + if (digit(2) < 0) { + lexError("invalid.binary.number"); + } else { + scanNumber(2); + } } else { putChar('0'); if (ch == '_') { diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 27980aa6061..c66840617c9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -252,6 +252,8 @@ compiler.err.intf.meth.cant.have.body=\ interface methods cannot have body compiler.err.invalid.annotation.member.type=\ invalid type for annotation member +compiler.err.invalid.binary.number=\ + binary numbers must contain at least one binary digit compiler.err.invalid.hex.number=\ hexadecimal numbers must contain at least one hexadecimal digit compiler.err.invalid.meth.decl.ret.type.req=\ diff --git a/langtools/test/tools/javac/literals/T6891079.java b/langtools/test/tools/javac/literals/T6891079.java new file mode 100644 index 00000000000..8d5edbcf71a --- /dev/null +++ b/langtools/test/tools/javac/literals/T6891079.java @@ -0,0 +1,12 @@ +/* @test /nodynamiccopyright/ + * @bug 6891079 + * @summary Compiler allows invalid binary literals 0b and oBL + * @compile/fail/ref=T6891079.out -XDrawDiagnostics T6891079.java + */ + +class Test { + int bi = 0B; + long bl = 0BL; + int xi = 0X; + long xl = 0XL; +} diff --git a/langtools/test/tools/javac/literals/T6891079.out b/langtools/test/tools/javac/literals/T6891079.out new file mode 100644 index 00000000000..4472d62bb7f --- /dev/null +++ b/langtools/test/tools/javac/literals/T6891079.out @@ -0,0 +1,7 @@ +T6891079.java:8:14: compiler.err.invalid.binary.number +T6891079.java:9:15: compiler.err.invalid.binary.number +T6891079.java:9:18: compiler.err.expected: token.identifier +T6891079.java:10:14: compiler.err.invalid.hex.number +T6891079.java:11:15: compiler.err.invalid.hex.number +T6891079.java:11:18: compiler.err.expected: token.identifier +6 errors From 9ecd8e48ca155d6b242c55dbcef243398fb9dc32 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Tue, 13 Oct 2009 16:29:31 -0700 Subject: [PATCH 041/172] 6889302: TraceExceptions output should include detail message Reviewed-by: twisti, jrose, kvn --- hotspot/src/share/vm/utilities/exceptions.cpp | 13 ++++++++----- hotspot/src/share/vm/utilities/exceptions.hpp | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/utilities/exceptions.cpp b/hotspot/src/share/vm/utilities/exceptions.cpp index 91c3cd733d3..6c9a0722d37 100644 --- a/hotspot/src/share/vm/utilities/exceptions.cpp +++ b/hotspot/src/share/vm/utilities/exceptions.cpp @@ -103,15 +103,18 @@ void Exceptions::_throw_oop(Thread* thread, const char* file, int line, oop exce _throw(thread, file, line, h_exception); } -void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception) { +void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) { assert(h_exception() != NULL, "exception should not be NULL"); // tracing (do this up front - so it works during boot strapping) if (TraceExceptions) { ttyLocker ttyl; ResourceMark rm; - tty->print_cr("Exception <%s> (" INTPTR_FORMAT " ) \nthrown [%s, line %d]\nfor thread " INTPTR_FORMAT, - h_exception->print_value_string(), (address)h_exception(), file, line, thread); + tty->print_cr("Exception <%s>%s%s (" INTPTR_FORMAT " ) \n" + "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT, + h_exception->print_value_string(), + message ? ": " : "", message ? message : "", + (address)h_exception(), file, line, thread); } // for AbortVMOnException flag NOT_PRODUCT(Exceptions::debug_check_abort(h_exception)); @@ -135,7 +138,7 @@ void Exceptions::_throw_msg(Thread* thread, const char* file, int line, symbolHa // Create and throw exception Handle h_cause(thread, NULL); Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain); - _throw(thread, file, line, h_exception); + _throw(thread, file, line, h_exception, message); } // Throw an exception with a message and a cause @@ -144,7 +147,7 @@ void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, sy if (special_exception(thread, file, line, h_name, message)) return; // Create and throw exception and init cause Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain); - _throw(thread, file, line, h_exception); + _throw(thread, file, line, h_exception, message); } // This version creates handles and calls the other version diff --git a/hotspot/src/share/vm/utilities/exceptions.hpp b/hotspot/src/share/vm/utilities/exceptions.hpp index ca01f455c75..8425e64eca2 100644 --- a/hotspot/src/share/vm/utilities/exceptions.hpp +++ b/hotspot/src/share/vm/utilities/exceptions.hpp @@ -103,7 +103,7 @@ class Exceptions { } ExceptionMsgToUtf8Mode; // Throw exceptions: w/o message, w/ message & with formatted message. static void _throw_oop(Thread* thread, const char* file, int line, oop exception); - static void _throw(Thread* thread, const char* file, int line, Handle exception); + static void _throw(Thread* thread, const char* file, int line, Handle exception, const char* msg = NULL); static void _throw_msg(Thread* thread, const char* file, int line, symbolHandle name, const char* message, Handle loader, Handle protection_domain); From f276d82e07b44c4a14f2e2814777b1606991bab1 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 13 Oct 2009 17:34:48 -0700 Subject: [PATCH 042/172] 6349921: (enum) Include links from java.lang.Enum to EnumSet and EnumMap Reviewed-by: martin --- jdk/src/share/classes/java/lang/Enum.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jdk/src/share/classes/java/lang/Enum.java b/jdk/src/share/classes/java/lang/Enum.java index 5df8146c1d4..30ae3d8697b 100644 --- a/jdk/src/share/classes/java/lang/Enum.java +++ b/jdk/src/share/classes/java/lang/Enum.java @@ -40,10 +40,17 @@ import java.io.ObjectStreamException; * Edition, §8.9. * + *

Note that when using an enumeration type as the type of a set + * or as the type of the keys in a map, specialized and efficient + * {@linkplain java.util.EnumSet set} and {@linkplain + * java.util.EnumMap map} implementations are available. + * * @param The enum type subclass * @author Josh Bloch * @author Neal Gafter * @see Class#getEnumConstants() + * @see java.util.EnumSet + * @see java.util.EnumMap * @since 1.5 */ public abstract class Enum> From 9a22acef055822913f53f6afd6e6521122e44648 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 13 Oct 2009 20:54:13 -0700 Subject: [PATCH 043/172] 6889656: assert(lo_lrg->lo_degree() || !lo_no_simplify,"Live range was lo-degree before coalesce Restore the original code: uint i = _hi_degree. Reviewed-by: never, jrose --- hotspot/src/share/vm/opto/chaitin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp index c16886c3e85..86f5f273876 100644 --- a/hotspot/src/share/vm/opto/chaitin.cpp +++ b/hotspot/src/share/vm/opto/chaitin.cpp @@ -990,7 +990,7 @@ void PhaseChaitin::Simplify( ) { // Find cheapest guy debug_only( int lo_no_simplify=0; ); - for( uint i = lrgs(lo_score)._next; i; i = lrgs(i)._next ) { + for( uint i = _hi_degree; i; i = lrgs(i)._next ) { assert( !(*_ifg->_yanked)[i], "" ); // It's just vaguely possible to move hi-degree to lo-degree without // going through a just-lo-degree stage: If you remove a double from From 998bcbaf4b1cad89f319e4fea296bfb6cb7a79a8 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 13 Oct 2009 22:32:31 -0700 Subject: [PATCH 044/172] 6889300: assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes") PhiNode::Ideal() should return TOP for Phi node with no users. Reviewed-by: never, jrose --- hotspot/src/share/vm/opto/cfgnode.cpp | 11 +++++++++-- hotspot/src/share/vm/opto/ifnode.cpp | 4 +++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp index 02c2ae01a21..b1da1c716d9 100644 --- a/hotspot/src/share/vm/opto/cfgnode.cpp +++ b/hotspot/src/share/vm/opto/cfgnode.cpp @@ -1531,6 +1531,8 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) { return NULL; // No change Node *top = phase->C->top(); + bool new_phi = (outcnt() == 0); // transforming new Phi + assert(!can_reshape || !new_phi, "for igvn new phi should be hooked"); // The are 2 situations when only one valid phi's input is left // (in addition to Region input). @@ -1550,6 +1552,12 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) { } } + if (can_reshape && outcnt() == 0) { + // set_req() above may kill outputs if Phi is referenced + // only by itself on the dead (top) control path. + return top; + } + Node* uin = unique_input(phase); if (uin == top) { // Simplest case: no alive inputs. if (can_reshape) // IGVN transformation @@ -1684,8 +1692,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) { // Equivalent code is in MemNode::Ideal_common Node *m = phase->transform(n); if (outcnt() == 0) { // Above transform() may kill us! - progress = phase->C->top(); - break; + return top; } // If transformed to a MergeMem, get the desired slice // Otherwise the returned node represents memory for every slice diff --git a/hotspot/src/share/vm/opto/ifnode.cpp b/hotspot/src/share/vm/opto/ifnode.cpp index 98cd93c3ca5..85ee07cda59 100644 --- a/hotspot/src/share/vm/opto/ifnode.cpp +++ b/hotspot/src/share/vm/opto/ifnode.cpp @@ -240,13 +240,13 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) { // as a single huge transform. igvn->register_new_node_with_optimizer( region_c ); igvn->register_new_node_with_optimizer( region_x ); - phi_x = phase->transform( phi_x ); // Prevent the untimely death of phi_x. Currently he has no uses. He is // about to get one. If this only use goes away, then phi_x will look dead. // However, he will be picking up some more uses down below. Node *hook = new (igvn->C, 4) Node(4); hook->init_req(0, phi_x); hook->init_req(1, phi_c); + phi_x = phase->transform( phi_x ); // Make the compare Node *cmp_c = phase->makecon(t); @@ -322,6 +322,7 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) { phi_s = PhiNode::make_blank(region_s,phi); phi_s->init_req( 1, phi_c ); phi_s->init_req( 2, phi_x ); + hook->add_req(phi_s); phi_s = phase->transform(phi_s); } proj_path_data = phi_s; @@ -333,6 +334,7 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) { phi_f = PhiNode::make_blank(region_f,phi); phi_f->init_req( 1, phi_c ); phi_f->init_req( 2, phi_x ); + hook->add_req(phi_f); phi_f = phase->transform(phi_f); } proj_path_data = phi_f; From 99d8a50297bb8489d0b11b4dc6a452d9f64f021b Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Wed, 14 Oct 2009 15:46:13 +0400 Subject: [PATCH 045/172] 6684916: jframe.setMaximizedBounds() has no effect in linux Specification should indicate that the feature may be unsupported on some platforms. Reviewed-by: art, dcherepanov --- jdk/src/share/classes/java/awt/Frame.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Frame.java b/jdk/src/share/classes/java/awt/Frame.java index 761b9b8420b..ea8c6154cf1 100644 --- a/jdk/src/share/classes/java/awt/Frame.java +++ b/jdk/src/share/classes/java/awt/Frame.java @@ -845,8 +845,11 @@ public class Frame extends Window implements MenuContainer { * others by setting those fields you want to accept from system * to Integer.MAX_VALUE. *

- * On some systems only the size portion of the bounds is taken - * into account. + * Note, the given maximized bounds are used as a hint for the native + * system, because the underlying platform may not support setting the + * location and/or size of the maximized windows. If that is the case, the + * provided values do not affect the appearance of the frame in the + * maximized state. * * @param bounds bounds for the maximized state * @see #getMaximizedBounds() From 370b3a923b84cc59cf3258544c25b31ed0ceeac0 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Wed, 14 Oct 2009 16:19:46 +0400 Subject: [PATCH 046/172] 6711717: PIT: Security Icon is hidden for FullScreen apps, WinXP Force hiding the security warning in FS exclusive mode. Reviewed-by: art, tdv --- .../share/classes/java/awt/AWTPermission.java | 12 ++++- .../solaris/classes/sun/awt/X11/XWindow.java | 20 ++++++++ .../classes/sun/awt/X11/XWindowPeer.java | 38 ++++++++------ .../classes/sun/awt/X11ComponentPeer.java | 3 +- .../classes/sun/awt/X11GraphicsDevice.java | 4 +- .../classes/sun/awt/Win32GraphicsDevice.java | 16 +++--- .../classes/sun/awt/windows/WWindowPeer.java | 3 ++ .../windows/native/sun/windows/awt_Window.cpp | 51 ++++++++++++++++++- .../windows/native/sun/windows/awt_Window.h | 11 ++++ 9 files changed, 132 insertions(+), 26 deletions(-) diff --git a/jdk/src/share/classes/java/awt/AWTPermission.java b/jdk/src/share/classes/java/awt/AWTPermission.java index b6eb03f62c7..84b400f53d9 100644 --- a/jdk/src/share/classes/java/awt/AWTPermission.java +++ b/jdk/src/share/classes/java/awt/AWTPermission.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, 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 @@ -92,7 +92,15 @@ import java.security.BasicPermission; * Enter full-screen exclusive mode * Entering full-screen exclusive mode allows direct access to * low-level graphics card memory. This could be used to spoof the - * system, since the program is in direct control of rendering. + * system, since the program is in direct control of rendering. Depending on + * the implementation, the security warning may not be shown for the windows + * used to enter the full-screen exclusive mode (assuming that the {@code + * fullScreenExclusive} permission has been granted to this application). Note + * that this behavior does not mean that the {@code + * showWindowWithoutWarningBanner} permission will be automatically granted to + * the application which has the {@code fullScreenExclusive} permission: + * non-full-screen windows will continue to be shown with the security + * warning. * * * diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java index f1c3c675b6c..9081aa5e545 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java @@ -1510,4 +1510,24 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { return new XAtomList(); } + /** + * Indicates if the window is currently in the FSEM. + * Synchronization: state lock. + */ + private boolean fullScreenExclusiveModeState = false; + + // Implementation of the X11ComponentPeer + @Override + public void setFullScreenExclusiveModeState(boolean state) { + synchronized (getStateLock()) { + fullScreenExclusiveModeState = state; + } + } + + public final boolean isFullScreenExclusiveMode() { + synchronized (getStateLock()) { + return fullScreenExclusiveModeState; + } + } + } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java index 076526fd653..51c55b96c2b 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java @@ -1080,31 +1080,39 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, updateSecurityWarningVisibility(); } + @Override + public void setFullScreenExclusiveModeState(boolean state) { + super.setFullScreenExclusiveModeState(state); + updateSecurityWarningVisibility(); + } + public void updateSecurityWarningVisibility() { if (warningWindow == null) { return; } - boolean show = false; - - int state = getWMState(); - if (!isVisible()) { return; // The warning window should already be hidden. } - // getWMState() always returns 0 (Withdrawn) for simple windows. Hence - // we ignore the state for such windows. - if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) { - if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == - getTarget()) - { - show = true; - } + boolean show = false; - if (isMouseAbove() || warningWindow.isMouseAbove()) - { - show = true; + if (!isFullScreenExclusiveMode()) { + int state = getWMState(); + + // getWMState() always returns 0 (Withdrawn) for simple windows. Hence + // we ignore the state for such windows. + if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) { + if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == + getTarget()) + { + show = true; + } + + if (isMouseAbove() || warningWindow.isMouseAbove()) + { + show = true; + } } } diff --git a/jdk/src/solaris/classes/sun/awt/X11ComponentPeer.java b/jdk/src/solaris/classes/sun/awt/X11ComponentPeer.java index a4a07506894..24b24809285 100644 --- a/jdk/src/solaris/classes/sun/awt/X11ComponentPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11ComponentPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, 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 @@ -39,4 +39,5 @@ public interface X11ComponentPeer { Rectangle getBounds(); Graphics getGraphics(); Object getTarget(); + void setFullScreenExclusiveModeState(boolean state); } diff --git a/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java b/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java index ed495b177ec..a009a16e234 100644 --- a/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java +++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 Sun Microsystems, 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 @@ -306,12 +306,14 @@ public class X11GraphicsDevice X11ComponentPeer peer = (X11ComponentPeer)w.getPeer(); if (peer != null) { enterFullScreenExclusive(peer.getContentWindow()); + peer.setFullScreenExclusiveModeState(true); } } private static void exitFullScreenExclusive(Window w) { X11ComponentPeer peer = (X11ComponentPeer)w.getPeer(); if (peer != null) { + peer.setFullScreenExclusiveModeState(false); exitFullScreenExclusive(peer.getContentWindow()); } } diff --git a/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java b/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java index 1da339ce9f1..7d8c17e6987 100644 --- a/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java +++ b/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java @@ -353,6 +353,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements } WWindowPeer peer = (WWindowPeer)old.getPeer(); if (peer != null) { + peer.setFullScreenExclusiveModeState(false); // we used to destroy the buffers on exiting fs mode, this // is no longer needed since fs change will cause a surface // data replacement @@ -370,12 +371,15 @@ public class Win32GraphicsDevice extends GraphicsDevice implements addFSWindowListener(w); // Enter full screen exclusive mode. WWindowPeer peer = (WWindowPeer)w.getPeer(); - synchronized(peer) { - enterFullScreenExclusive(screen, peer); - // Note: removed replaceSurfaceData() call because - // changing the window size or making it visible - // will cause this anyway, and both of these events happen - // as part of switching into fullscreen mode. + if (peer != null) { + synchronized(peer) { + enterFullScreenExclusive(screen, peer); + // Note: removed replaceSurfaceData() call because + // changing the window size or making it visible + // will cause this anyway, and both of these events happen + // as part of switching into fullscreen mode. + } + peer.setFullScreenExclusiveModeState(true); } // fix for 4868278 diff --git a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java index fbb7442ba7d..3f11839e8cc 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java @@ -510,6 +510,9 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, private native int getScreenImOn(); + // Used in Win32GraphicsDevice. + public final native void setFullScreenExclusiveModeState(boolean state); + /* * ----END DISPLAY CHANGE SUPPORT---- */ diff --git a/jdk/src/windows/native/sun/windows/awt_Window.cpp b/jdk/src/windows/native/sun/windows/awt_Window.cpp index 4c902c3fb47..8bb5c900219 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp @@ -143,6 +143,11 @@ struct RepositionSecurityWarningStruct { jobject window; }; +struct SetFullScreenExclusiveModeStateStruct { + jobject window; + jboolean isFSEMState; +}; + /************************************************************************ * AwtWindow fields @@ -915,7 +920,9 @@ void AwtWindow::UpdateSecurityWarningVisibility() bool show = false; - if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED) { + if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED && + !isFullScreenExclusiveMode()) + { if (AwtComponent::GetFocusedWindow() == GetHWnd()) { show = true; } @@ -2954,6 +2961,25 @@ void AwtWindow::_UpdateWindow(void* param) delete uws; } +void AwtWindow::_SetFullScreenExclusiveModeState(void *param) +{ + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + + SetFullScreenExclusiveModeStateStruct * data = + (SetFullScreenExclusiveModeStateStruct*)param; + jobject self = data->window; + jboolean state = data->isFSEMState; + + PDATA pData; + JNI_CHECK_PEER_GOTO(self, ret); + AwtWindow *window = (AwtWindow *)pData; + + window->setFullScreenExclusiveModeState(state != 0); + + ret: + env->DeleteGlobalRef(self); + delete data; +} extern "C" { @@ -3333,6 +3359,29 @@ Java_sun_awt_windows_WWindowPeer_getScreenImOn(JNIEnv *env, jobject self) CATCH_BAD_ALLOC_RET(-1); } +/* + * Class: sun_awt_windows_WWindowPeer + * Method: setFullScreenExclusiveModeState + * Signature: (Z)V + */ +JNIEXPORT void JNICALL +Java_sun_awt_windows_WWindowPeer_setFullScreenExclusiveModeState(JNIEnv *env, + jobject self, jboolean state) +{ + TRY; + + SetFullScreenExclusiveModeStateStruct *data = + new SetFullScreenExclusiveModeStateStruct; + data->window = env->NewGlobalRef(self); + data->isFSEMState = state; + + AwtToolkit::GetInstance().SyncCall( + AwtWindow::_SetFullScreenExclusiveModeState, data); + // global ref and data are deleted in the invoked method + + CATCH_BAD_ALLOC; +} + /* * Class: sun_awt_windows_WWindowPeer * Method: modalDisable diff --git a/jdk/src/windows/native/sun/windows/awt_Window.h b/jdk/src/windows/native/sun/windows/awt_Window.h index 1d238b44dac..001062835e3 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.h +++ b/jdk/src/windows/native/sun/windows/awt_Window.h @@ -229,6 +229,7 @@ public: static void _SetOpaque(void* param); static void _UpdateWindow(void* param); static void _RepositionSecurityWarning(void* param); + static void _SetFullScreenExclusiveModeState(void* param); inline static BOOL IsResizing() { return sm_resizing; @@ -331,6 +332,16 @@ private: static void SetLayered(HWND window, bool layered); static bool IsLayered(HWND window); + BOOL fullScreenExclusiveModeState; + inline void setFullScreenExclusiveModeState(BOOL isEntered) { + fullScreenExclusiveModeState = isEntered; + UpdateSecurityWarningVisibility(); + } + inline BOOL isFullScreenExclusiveMode() { + return fullScreenExclusiveModeState; + } + + public: void UpdateSecurityWarningVisibility(); static bool IsWarningWindow(HWND hWnd); From b32d27a2532735a5508ec748c0e530bdee7f7fd0 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Wed, 14 Oct 2009 16:32:38 +0400 Subject: [PATCH 047/172] 6885735: closed/java/awt/Component/DisablingLWDisabledHW/DisablingLWDisabledHW.html fails Use isRecursivelyVisibleUpToHeavyweightContainer() instead of isRecursivelyVisible() to determine if the peer needs to be hidden. Reviewed-by: art, dcherepanov --- jdk/src/share/classes/java/awt/Component.java | 11 +++++----- jdk/src/share/classes/java/awt/Container.java | 21 +++++++++++++++---- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index 59a43e7fe80..2c1d08596be 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -6720,12 +6720,13 @@ public abstract class Component implements ImageObserver, MenuContainer, } } } else { - // It's native. If the parent is lightweight it - // will need some help. - Container parent = this.parent; - if (parent != null && parent.peer instanceof LightweightPeer) { + // It's native. If the parent is lightweight it will need some + // help. + Container parent = getContainer(); + if (parent != null && parent.isLightweight()) { relocateComponent(); - if (!isRecursivelyVisible()) { + if (!parent.isRecursivelyVisibleUpToHeavyweightContainer()) + { peer.setVisible(false); } } diff --git a/jdk/src/share/classes/java/awt/Container.java b/jdk/src/share/classes/java/awt/Container.java index e3372409c06..5d4e95d9df5 100644 --- a/jdk/src/share/classes/java/awt/Container.java +++ b/jdk/src/share/classes/java/awt/Container.java @@ -4092,16 +4092,29 @@ public class Container extends Component { } } - /* + /** + * Checks if the container and its direct lightweight containers are + * visible. + * * Consider the heavyweight container hides or shows the HW descendants * automatically. Therefore we care of LW containers' visibility only. + * + * This method MUST be invoked under the TreeLock. */ - private boolean isRecursivelyVisibleUpToHeavyweightContainer() { + final boolean isRecursivelyVisibleUpToHeavyweightContainer() { if (!isLightweight()) { return true; } - return isVisible() && (getContainer() == null || - getContainer().isRecursivelyVisibleUpToHeavyweightContainer()); + + for (Container cont = getContainer(); + cont != null && cont.isLightweight(); + cont = cont.getContainer()) + { + if (!cont.isVisible()) { + return false; + } + } + return true; } @Override From 581d01d8c4e037c0fae2b1271af8b6bcd59fb364 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Wed, 14 Oct 2009 09:36:31 -0400 Subject: [PATCH 048/172] 6885667: CertPath/CertPathValidatorTest/bugs/bug6383078 fails on jdk6u18/b02, jdk7/pit/b73 and passes on b72 Wrap all OCSP exceptions in CertPathValidatorException so that we can fallback to CRLs, if enabled. Reviewed-by: dgu, xuelei --- .../classes/sun/security/provider/certpath/OCSP.java | 4 ++++ .../sun/security/provider/certpath/OCSPChecker.java | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/sun/security/provider/certpath/OCSP.java b/jdk/src/share/classes/sun/security/provider/certpath/OCSP.java index 2665de6d680..dfdd846c5b8 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/OCSP.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSP.java @@ -64,6 +64,8 @@ public final class OCSP { private static final Debug debug = Debug.getInstance("certpath"); + private static final int CONNECT_TIMEOUT = 15000; // 15 seconds + private OCSP() {} /** @@ -176,6 +178,8 @@ public final class OCSP { debug.println("connecting to OCSP service at: " + url); } HttpURLConnection con = (HttpURLConnection)url.openConnection(); + con.setConnectTimeout(CONNECT_TIMEOUT); + con.setReadTimeout(CONNECT_TIMEOUT); con.setDoOutput(true); con.setDoInput(true); con.setRequestMethod("POST"); diff --git a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java index 6f72c7ec185..499a5912aca 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java @@ -25,7 +25,6 @@ package sun.security.provider.certpath; -import java.io.IOException; import java.math.BigInteger; import java.util.*; import java.security.AccessController; @@ -335,10 +334,11 @@ class OCSPChecker extends PKIXCertPathChecker { (issuerCert, currCertImpl.getSerialNumberObject()); response = OCSP.check(Collections.singletonList(certId), uri, responderCert, pkixParams.getDate()); - } catch (IOException ioe) { - // should allow this to pass if network failures are acceptable + } catch (Exception e) { + // Wrap all exceptions in CertPathValidatorException so that + // we can fallback to CRLs, if enabled. throw new CertPathValidatorException - ("Unable to send OCSP request", ioe); + ("Unable to send OCSP request", e); } RevocationStatus rs = (RevocationStatus) response.getSingleResponse(certId); From e507e02d67793bcadc4a527adccd2f5aa1190a6d Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Wed, 14 Oct 2009 19:23:15 +0400 Subject: [PATCH 049/172] 6884960: java/awt/Window/TranslucentJAppletTest/TranslucentJAppletTest.java fails Support painting heavyweight components in transparent windows. Reviewed-by: art, alexp --- .../share/classes/javax/swing/JComponent.java | 20 +++++++++---- .../sun/awt/windows/WComponentPeer.java | 28 ++++++++++++++++++- .../classes/sun/awt/windows/WWindowPeer.java | 8 +++++- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JComponent.java b/jdk/src/share/classes/javax/swing/JComponent.java index f0be74509f9..6c97ebd5e71 100644 --- a/jdk/src/share/classes/javax/swing/JComponent.java +++ b/jdk/src/share/classes/javax/swing/JComponent.java @@ -795,7 +795,6 @@ public abstract class JComponent extends Container implements Serializable, * @see java.awt.Container#paint */ protected void paintChildren(Graphics g) { - boolean isJComponent; Graphics sg = g; synchronized(getTreeLock()) { @@ -826,12 +825,21 @@ public abstract class JComponent extends Container implements Serializable, } } boolean printing = getFlag(IS_PRINTING); + final Window window = SwingUtilities.getWindowAncestor(this); + final boolean isWindowOpaque = window == null || window.isOpaque(); for (; i >= 0 ; i--) { Component comp = getComponent(i); - isJComponent = (comp instanceof JComponent); - if (comp != null && - (isJComponent || isLightweightComponent(comp)) && - (comp.isVisible() == true)) { + if (comp == null) { + continue; + } + + final boolean isJComponent = comp instanceof JComponent; + + // Enable painting of heavyweights in non-opaque windows. + // See 6884960 + if ((!isWindowOpaque || isJComponent || + isLightweightComponent(comp)) && comp.isVisible()) + { Rectangle cr; cr = comp.getBounds(tmpRect); @@ -887,6 +895,8 @@ public abstract class JComponent extends Container implements Serializable, } } } else { + // The component is either lightweight, or + // heavyweight in a non-opaque window if (!printing) { comp.paint(cg); } diff --git a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java index 04b3e99c26b..66ec4558f1e 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java @@ -551,8 +551,34 @@ public abstract class WComponentPeer extends WObjectPeer final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); public Graphics getGraphics() { + if (isDisposed()) { + return null; + } + + Component target = (Component)getTarget(); + Window window = SunToolkit.getContainingWindow(target); + if (window != null && !window.isOpaque()) { + // Non-opaque windows do not support heavyweight children. + // Redirect all painting to the Window's Graphics instead. + // The caller is responsible for calling the + // WindowPeer.updateWindow() after painting has finished. + int x = 0, y = 0; + for (Component c = target; c != window; c = c.getParent()) { + x += c.getX(); + y += c.getY(); + } + + Graphics g = + ((WWindowPeer)window.getPeer()).getTranslucentGraphics(); + + g.translate(x, y); + g.clipRect(0, 0, target.getWidth(), target.getHeight()); + + return g; + } + SurfaceData surfaceData = this.surfaceData; - if (!isDisposed() && surfaceData != null) { + if (surfaceData != null) { /* Fix for bug 4746122. Color and Font shouldn't be null */ Color bgColor = background; if (bgColor == null) { diff --git a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java index 3f11839e8cc..26fe048cdca 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java @@ -578,11 +578,17 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, } } + public final Graphics getTranslucentGraphics() { + synchronized (getStateLock()) { + return isOpaque ? null : painter.getBackBuffer(false).getGraphics(); + } + } + @Override public Graphics getGraphics() { synchronized (getStateLock()) { if (!isOpaque) { - return painter.getBackBuffer(false).getGraphics(); + return getTranslucentGraphics(); } } return super.getGraphics(); From 6af1a61656972db49466b6deea3cf86626b60568 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 14 Oct 2009 10:36:57 -0700 Subject: [PATCH 050/172] 6889869: assert(!Interpreter::bytecode_should_reexecute(code),"should not reexecute") Reviewed-by: jrose, kvn, cfang, twisti --- hotspot/src/share/vm/code/debugInfoRec.cpp | 3 +-- hotspot/src/share/vm/code/pcDesc.hpp | 8 ++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/code/debugInfoRec.cpp b/hotspot/src/share/vm/code/debugInfoRec.cpp index c1bbe751b9f..fa24eb7c4c8 100644 --- a/hotspot/src/share/vm/code/debugInfoRec.cpp +++ b/hotspot/src/share/vm/code/debugInfoRec.cpp @@ -356,8 +356,7 @@ void DebugInformationRecorder::end_scopes(int pc_offset, bool is_safepoint) { // search forward until it finds last. // In addition, it does not matter if the last PcDesc // is for a safepoint or not. - if (_prev_safepoint_pc < prev->pc_offset() && - prev->scope_decode_offset() == last->scope_decode_offset()) { + if (_prev_safepoint_pc < prev->pc_offset() && prev->is_same_info(last)) { assert(prev == last-1, "sane"); prev->set_pc_offset(pc_offset); _pcs_length -= 1; diff --git a/hotspot/src/share/vm/code/pcDesc.hpp b/hotspot/src/share/vm/code/pcDesc.hpp index 36f60d787f3..de9334b4cee 100644 --- a/hotspot/src/share/vm/code/pcDesc.hpp +++ b/hotspot/src/share/vm/code/pcDesc.hpp @@ -39,6 +39,7 @@ class PcDesc VALUE_OBJ_CLASS_SPEC { struct { unsigned int reexecute: 1; } bits; + bool operator ==(const PcDescFlags& other) { return word == other.word; } } _flags; public: @@ -64,6 +65,13 @@ class PcDesc VALUE_OBJ_CLASS_SPEC { bool should_reexecute() const { return _flags.bits.reexecute; } void set_should_reexecute(bool z) { _flags.bits.reexecute = z; } + // Does pd refer to the same information as pd? + bool is_same_info(const PcDesc* pd) { + return _scope_decode_offset == pd->_scope_decode_offset && + _obj_decode_offset == pd->_obj_decode_offset && + _flags == pd->_flags; + } + // Returns the real pc address real_pc(const nmethod* code) const; From 6b576be53ca726c3569365fd94cbda68e2646d53 Mon Sep 17 00:00:00 2001 From: Jennifer Godinez Date: Wed, 14 Oct 2009 10:44:32 -0700 Subject: [PATCH 051/172] 6890945: Typo in sentence about thread safety Reviewed-by: prr --- .../javax/print/attribute/standard/PrinterStateReasons.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java b/jdk/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java index 14225b90e46..2b0e8d2ab0c 100644 --- a/jdk/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java +++ b/jdk/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java @@ -65,7 +65,7 @@ import javax.print.attribute.PrintServiceAttribute; * PrinterStateReason PrinterStateReason} objects to an existing * PrinterStateReasons object and remove them again. However, like class * {@link java.util.HashMap java.util.HashMap}, class PrinterStateReasons is - * bot multiple thread safe. If a PrinterStateReasons object will be used by + * not multiple thread safe. If a PrinterStateReasons object will be used by * multiple threads, be sure to synchronize its operations (e.g., using a * synchronized map view obtained from class {@link java.util.Collections * java.util.Collections}). From 3d9a536c1a87f6b4f1a5da6ac6ebb9c5d4d6ad28 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 14 Oct 2009 11:42:59 -0700 Subject: [PATCH 052/172] 6722084: JPRT make file doesn't create required symbolic link to libjvm.so Use -y zip option to preserve symbolic links. Reviewed-by: never, jcoomes, kamg --- hotspot/make/jprt.gmk | 13 ++++++++++--- hotspot/make/linux/makefiles/defs.make | 6 ++++-- hotspot/make/solaris/makefiles/defs.make | 6 ++++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/hotspot/make/jprt.gmk b/hotspot/make/jprt.gmk index e43f7638c1e..044dd528ea6 100644 --- a/hotspot/make/jprt.gmk +++ b/hotspot/make/jprt.gmk @@ -29,17 +29,24 @@ ifdef JPRT_BUILD_VERSION MILESTONE=$(JPRT_BUILD_VERSION) endif +ifeq ($(OSNAME),windows) + ZIPFLAGS=-q +else + # store symbolic links as the link + ZIPFLAGS=-q -y +endif + jprt_build_product: all_product copy_product_jdk export_product_jdk ( $(CD) $(JDK_IMAGE_DIR) && \ - $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . ) + $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . ) jprt_build_fastdebug: all_fastdebug copy_fastdebug_jdk export_fastdebug_jdk ( $(CD) $(JDK_IMAGE_DIR)/fastdebug && \ - $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . ) + $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . ) jprt_build_debug: all_debug copy_debug_jdk export_debug_jdk ( $(CD) $(JDK_IMAGE_DIR)/debug && \ - $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . ) + $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . ) .PHONY: jprt_build_product jprt_build_fastdebug jprt_build_debug diff --git a/hotspot/make/linux/makefiles/defs.make b/hotspot/make/linux/makefiles/defs.make index f1a8c5dd718..69f91cc171a 100644 --- a/hotspot/make/linux/makefiles/defs.make +++ b/hotspot/make/linux/makefiles/defs.make @@ -104,15 +104,17 @@ JDK_INCLUDE_SUBDIR=linux VM_DEBUG=jvmg EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html + +# client and server subdirectories have symbolic links to ../libjsig.so +EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so + EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt -EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjsig.so EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so ifneq ($(ZERO_BUILD), true) ifeq ($(ARCH_DATA_MODEL), 32) EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjsig.so EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar diff --git a/hotspot/make/solaris/makefiles/defs.make b/hotspot/make/solaris/makefiles/defs.make index 625399a72b3..bf62108680e 100644 --- a/hotspot/make/solaris/makefiles/defs.make +++ b/hotspot/make/solaris/makefiles/defs.make @@ -65,16 +65,18 @@ JDK_INCLUDE_SUBDIR=solaris VM_DEBUG=jvmg EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html + +# client and server subdirectories have symbolic links to ../libjsig.so +EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so + EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt -EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjsig.so EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.so EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.so ifeq ($(ARCH_DATA_MODEL), 32) EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjsig.so EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.so EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.so From 34324e30c0c561026045ba968629f8a8b3f9c57d Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 14 Oct 2009 15:03:32 -0700 Subject: [PATCH 053/172] 6890984: Comparison of 2 arrays could cause VM crash Restore original null checks. Reviewed-by: never, cfang --- hotspot/src/cpu/sparc/vm/sparc.ad | 2 +- hotspot/src/cpu/x86/vm/assembler_x86.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad index 151b3087021..3c26cbb8869 100644 --- a/hotspot/src/cpu/sparc/vm/sparc.ad +++ b/hotspot/src/cpu/sparc/vm/sparc.ad @@ -3016,7 +3016,7 @@ enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI r // return true if the same array __ cmp(ary1_reg, ary2_reg); - __ br(Assembler::equal, true, Assembler::pn, Ldone); + __ brx(Assembler::equal, true, Assembler::pn, Ldone); __ delayed()->add(G0, 1, result_reg); // equal __ br_null(ary1_reg, true, Assembler::pn, Ldone); diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index b742a5a36a7..07509493038 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -8634,8 +8634,10 @@ void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Regist if (is_array_equ) { // Need additional checks for arrays_equals. - andptr(ary1, ary2); - jcc(Assembler::zero, FALSE_LABEL); // One pointer is NULL + testptr(ary1, ary1); + jcc(Assembler::zero, FALSE_LABEL); + testptr(ary2, ary2); + jcc(Assembler::zero, FALSE_LABEL); // Check the lengths movl(limit, Address(ary1, length_offset)); From 44767bbfbea2f204c4839434c0114c45f1e15c1b Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 14 Oct 2009 15:41:28 -0700 Subject: [PATCH 054/172] 6838467: JSR199 FileObjects don't obey general contract of equals Reviewed-by: darcy --- .../sun/tools/javac/file/BaseFileObject.java | 8 + .../tools/javac/file/JavacFileManager.java | 2 +- .../tools/javac/file/RegularFileObject.java | 58 ++-- .../sun/tools/javac/file/SymbolArchive.java | 4 +- .../com/sun/tools/javac/file/ZipArchive.java | 69 +++-- .../sun/tools/javac/file/ZipFileIndex.java | 11 + .../tools/javac/file/ZipFileIndexArchive.java | 14 +- .../com/sun/tools/javac/jvm/ClassReader.java | 10 + .../tools/javac/api/6440528/T6440528.java | 6 +- langtools/test/tools/javac/api/T6838467.java | 249 ++++++++++++++++++ 10 files changed, 384 insertions(+), 47 deletions(-) create mode 100644 langtools/test/tools/javac/api/T6838467.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java b/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java index f2f18374562..6435e05a04c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java @@ -120,6 +120,14 @@ public abstract class BaseFileObject implements JavaFileObject { } + // force subtypes to define equals + @Override + public abstract boolean equals(Object other); + + // force subtypes to define hashCode + @Override + public abstract int hashCode(); + /** The file manager that created this JavaFileObject. */ protected final JavacFileManager fileManager; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java index 405c27675fa..23f169b5392 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -968,7 +968,7 @@ public class JavacFileManager implements StandardJavaFileManager { } else { File siblingDir = null; if (sibling != null && sibling instanceof RegularFileObject) { - siblingDir = ((RegularFileObject)sibling).f.getParentFile(); + siblingDir = ((RegularFileObject)sibling).file.getParentFile(); } return new RegularFileObject(this, new File(siblingDir, fileName.basename())); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java b/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java index 59d5d1c9526..aa4fa48ff29 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java @@ -33,6 +33,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; import java.net.URI; import java.nio.ByteBuffer; import java.nio.CharBuffer; @@ -53,7 +55,8 @@ class RegularFileObject extends BaseFileObject { */ private boolean hasParents = false; private String name; - final File f; + final File file; + private Reference absFileRef; public RegularFileObject(JavacFileManager fileManager, File f) { this(fileManager, f.getName(), f); @@ -65,17 +68,17 @@ class RegularFileObject extends BaseFileObject { throw new IllegalArgumentException("directories not supported"); } this.name = name; - this.f = f; + this.file = f; } @Override public URI toUri() { - return f.toURI().normalize(); + return file.toURI().normalize(); } @Override public String getName() { - return f.getPath(); + return file.getPath(); } @Override @@ -90,20 +93,20 @@ class RegularFileObject extends BaseFileObject { @Override public InputStream openInputStream() throws IOException { - return new FileInputStream(f); + return new FileInputStream(file); } @Override public OutputStream openOutputStream() throws IOException { ensureParentDirectoriesExist(); - return new FileOutputStream(f); + return new FileOutputStream(file); } @Override public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { CharBuffer cb = fileManager.getCachedContent(this); if (cb == null) { - InputStream in = new FileInputStream(f); + InputStream in = new FileInputStream(file); try { ByteBuffer bb = fileManager.makeByteBuffer(in); JavaFileObject prev = fileManager.log.useSource(this); @@ -126,17 +129,17 @@ class RegularFileObject extends BaseFileObject { @Override public Writer openWriter() throws IOException { ensureParentDirectoriesExist(); - return new OutputStreamWriter(new FileOutputStream(f), fileManager.getEncodingName()); + return new OutputStreamWriter(new FileOutputStream(file), fileManager.getEncodingName()); } @Override public long getLastModified() { - return f.lastModified(); + return file.lastModified(); } @Override public boolean delete() { - return f.delete(); + return file.delete(); } @Override @@ -146,7 +149,7 @@ class RegularFileObject extends BaseFileObject { @Override protected String inferBinaryName(Iterable path) { - String fPath = f.getPath(); + String fPath = file.getPath(); //System.err.println("RegularFileObject " + file + " " +r.getPath()); for (File dir: path) { //System.err.println("dir: " + dir); @@ -178,7 +181,7 @@ class RegularFileObject extends BaseFileObject { if (name.equalsIgnoreCase(n)) { try { // allow for Windows - return f.getCanonicalFile().getName().equals(n); + return file.getCanonicalFile().getName().equals(n); } catch (IOException e) { } } @@ -187,7 +190,7 @@ class RegularFileObject extends BaseFileObject { private void ensureParentDirectoriesExist() throws IOException { if (!hasParents) { - File parent = f.getParentFile(); + File parent = file.getParentFile(); if (parent != null && !parent.exists()) { if (!parent.mkdirs()) { if (!parent.exists() || !parent.isDirectory()) { @@ -199,21 +202,34 @@ class RegularFileObject extends BaseFileObject { } } + /** + * Check if two file objects are equal. + * Two RegularFileObjects are equal if the absolute paths of the underlying + * files are equal. + */ @Override public boolean equals(Object other) { - if (!(other instanceof RegularFileObject)) { + if (this == other) + return true; + + if (!(other instanceof RegularFileObject)) return false; - } + RegularFileObject o = (RegularFileObject) other; - try { - return f.equals(o.f) || f.getCanonicalFile().equals(o.f.getCanonicalFile()); - } catch (IOException e) { - return false; - } + return getAbsoluteFile().equals(o.getAbsoluteFile()); } @Override public int hashCode() { - return f.hashCode(); + return getAbsoluteFile().hashCode(); + } + + private File getAbsoluteFile() { + File absFile = (absFileRef == null ? null : absFileRef.get()); + if (absFile == null) { + absFile = file.getAbsoluteFile(); + absFileRef = new SoftReference(absFile); + } + return absFile; } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java b/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java index c564d4c7673..ed2ed3620f2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java @@ -76,13 +76,13 @@ public class SymbolArchive extends ZipArchive { @Override public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) { RelativeDirectory prefix_subdir = new RelativeDirectory(prefix, subdirectory.path); - ZipEntry ze = new RelativeFile(prefix_subdir, file).getZipEntry(zdir); + ZipEntry ze = new RelativeFile(prefix_subdir, file).getZipEntry(zfile); return new SymbolFileObject(this, file, ze); } @Override public String toString() { - return "SymbolArchive[" + zdir.getName() + "]"; + return "SymbolArchive[" + zfile.getName() + "]"; } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java b/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java index eae86b1de00..d56e6b2a865 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java @@ -47,6 +47,8 @@ import com.sun.tools.javac.file.JavacFileManager.Archive; import com.sun.tools.javac.file.RelativePath.RelativeDirectory; import com.sun.tools.javac.file.RelativePath.RelativeFile; import com.sun.tools.javac.util.List; +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; /** *

This is NOT part of any API supported by Sun Microsystems. @@ -56,20 +58,20 @@ import com.sun.tools.javac.util.List; */ public class ZipArchive implements Archive { - public ZipArchive(JavacFileManager fm, ZipFile zdir) throws IOException { - this(fm, zdir, true); + public ZipArchive(JavacFileManager fm, ZipFile zfile) throws IOException { + this(fm, zfile, true); } - protected ZipArchive(JavacFileManager fm, ZipFile zdir, boolean initMap) throws IOException { + protected ZipArchive(JavacFileManager fm, ZipFile zfile, boolean initMap) throws IOException { this.fileManager = fm; - this.zdir = zdir; + this.zfile = zfile; this.map = new HashMap>(); if (initMap) initMap(); } protected void initMap() throws IOException { - for (Enumeration e = zdir.entries(); e.hasMoreElements(); ) { + for (Enumeration e = zfile.entries(); e.hasMoreElements(); ) { ZipEntry entry; try { entry = e.nextElement(); @@ -110,7 +112,7 @@ public class ZipArchive implements Archive { } public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) { - ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zdir); + ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zfile); return new ZipFileObject(this, file, ze); } @@ -119,17 +121,39 @@ public class ZipArchive implements Archive { } public void close() throws IOException { - zdir.close(); + zfile.close(); } @Override public String toString() { - return "ZipArchive[" + zdir.getName() + "]"; + return "ZipArchive[" + zfile.getName() + "]"; } + private File getAbsoluteFile() { + File absFile = (absFileRef == null ? null : absFileRef.get()); + if (absFile == null) { + absFile = new File(zfile.getName()).getAbsoluteFile(); + absFileRef = new SoftReference(absFile); + } + return absFile; + } + + /** + * The file manager that created this archive. + */ protected JavacFileManager fileManager; + /** + * The index for the contents of this archive. + */ protected final Map> map; - protected final ZipFile zdir; + /** + * The zip file for the archive. + */ + protected final ZipFile zfile; + /** + * A reference to the absolute filename for the zip file for the archive. + */ + protected Reference absFileRef; /** * A subclass of JavaFileObject representing zip entries. @@ -148,18 +172,18 @@ public class ZipArchive implements Archive { } public URI toUri() { - File zipFile = new File(zarch.zdir.getName()); + File zipFile = new File(zarch.zfile.getName()); return createJarUri(zipFile, entry.getName()); } @Override public String getName() { - return zarch.zdir.getName() + "(" + entry.getName() + ")"; + return zarch.zfile.getName() + "(" + entry.getName() + ")"; } @Override public String getShortName() { - return new File(zarch.zdir.getName()).getName() + "(" + entry + ")"; + return new File(zarch.zfile.getName()).getName() + "(" + entry + ")"; } @Override @@ -169,7 +193,7 @@ public class ZipArchive implements Archive { @Override public InputStream openInputStream() throws IOException { - return zarch.zdir.getInputStream(entry); + return zarch.zfile.getInputStream(entry); } @Override @@ -181,7 +205,7 @@ public class ZipArchive implements Archive { public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { CharBuffer cb = fileManager.getCachedContent(this); if (cb == null) { - InputStream in = zarch.zdir.getInputStream(entry); + InputStream in = zarch.zfile.getInputStream(entry); try { ByteBuffer bb = fileManager.makeByteBuffer(in); JavaFileObject prev = fileManager.log.useSource(this); @@ -237,18 +261,27 @@ public class ZipArchive implements Archive { return name.equals(cn + k.extension); } + /** + * Check if two file objects are equal. + * Two ZipFileObjects are equal if the absolute paths of the underlying + * zip files are equal and if the paths within those zip files are equal. + */ @Override public boolean equals(Object other) { - if (!(other instanceof ZipFileObject)) { + if (this == other) + return true; + + if (!(other instanceof ZipFileObject)) return false; - } + ZipFileObject o = (ZipFileObject) other; - return zarch.zdir.equals(o.zarch.zdir) || name.equals(o.name); + return zarch.getAbsoluteFile().equals(o.zarch.getAbsoluteFile()) + && name.equals(o.name); } @Override public int hashCode() { - return zarch.zdir.hashCode() + name.hashCode(); + return zarch.getAbsoluteFile().hashCode() + name.hashCode(); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java index f39359992a1..6ea261c0fe0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java @@ -30,6 +30,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; +import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.Arrays; @@ -89,6 +90,7 @@ public class ZipFileIndex { // ZipFileIndex data entries private File zipFile; + private Reference absFileRef; private long zipFileLastModified = NOT_MODIFIED; private RandomAccessFile zipRandomFile; private Entry[] entries; @@ -1215,6 +1217,15 @@ public class ZipFileIndex { return zipFile; } + File getAbsoluteFile() { + File absFile = (absFileRef == null ? null : absFileRef.get()); + if (absFile == null) { + absFile = zipFile.getAbsoluteFile(); + absFileRef = new SoftReference(absFile); + } + return absFile; + } + private RelativeDirectory getRelativeDirectory(String path) { RelativeDirectory rd; SoftReference ref = relativeDirectoryCache.get(path); diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java index c97e73b493b..500d4cf08b5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java @@ -219,17 +219,27 @@ public class ZipFileIndexArchive implements Archive { return name.equals(cn + k.extension); } + /** + * Check if two file objects are equal. + * Two ZipFileIndexFileObjects are equal if the absolute paths of the underlying + * zip files are equal and if the paths within those zip files are equal. + */ @Override public boolean equals(Object other) { + if (this == other) + return true; + if (!(other instanceof ZipFileIndexFileObject)) return false; + ZipFileIndexFileObject o = (ZipFileIndexFileObject) other; - return entry.equals(o.entry); + return zfIndex.getAbsoluteFile().equals(o.zfIndex.getAbsoluteFile()) + && name.equals(o.name); } @Override public int hashCode() { - return zipName.hashCode() + (name.hashCode() << 10); + return zfIndex.getAbsoluteFile().hashCode() + name.hashCode(); } private String getPrefixedEntryName() { diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 1d2614ada74..c8446b5e42d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -2632,10 +2632,20 @@ public class ClassReader implements Completer { return true; // fail-safe mode } + /** + * Check if two file objects are equal. + * SourceFileObjects are just placeholder objects for the value of a + * SourceFile attribute, and do not directly represent specific files. + * Two SourceFileObjects are equal if their names are equal. + */ @Override public boolean equals(Object other) { + if (this == other) + return true; + if (!(other instanceof SourceFileObject)) return false; + SourceFileObject o = (SourceFileObject) other; return name.equals(o.name); } diff --git a/langtools/test/tools/javac/api/6440528/T6440528.java b/langtools/test/tools/javac/api/6440528/T6440528.java index d63bd116892..3194670a793 100644 --- a/langtools/test/tools/javac/api/6440528/T6440528.java +++ b/langtools/test/tools/javac/api/6440528/T6440528.java @@ -59,9 +59,9 @@ public class T6440528 extends ToolTester { } private File getUnderlyingFile(Object o) throws Exception { - Field f = o.getClass().getDeclaredField("f"); - f.setAccessible(true); - return (File)f.get(o); + Field file = o.getClass().getDeclaredField("file"); + file.setAccessible(true); + return (File)file.get(o); } public static void main(String... args) throws Exception { diff --git a/langtools/test/tools/javac/api/T6838467.java b/langtools/test/tools/javac/api/T6838467.java new file mode 100644 index 00000000000..15837bc34c7 --- /dev/null +++ b/langtools/test/tools/javac/api/T6838467.java @@ -0,0 +1,249 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6838467 + * @summary JSR199 FileObjects don't obey general contract of equals. + */ + +import java.io.*; +import java.util.*; +import java.util.zip.*; +import javax.tools.*; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.util.Context; + +public class T6838467 { + boolean fileSystemIsCaseSignificant = !new File("a").equals(new File("A")); + + enum FileKind { + DIR("dir"), + ZIP("zip"), + ZIPFILEINDEX("zip"); + FileKind(String path) { + file = new File(path); + } + final File file; + }; + + enum CompareKind { + SAME { + File other(File f) { return f; } + }, + ABSOLUTE { + File other(File f) { return f.getAbsoluteFile(); } + }, + DIFFERENT { + File other(File f) { return new File("not_" + f.getPath()); } + }, + CASEEQUIV { + File other(File f) { return new File(f.getPath().toUpperCase()); } + }; + abstract File other(File f); + }; + + String[] paths = { "p/A.java", "p/B.java", "p/C.java" }; + + public static void main(String... args) throws Exception { + new T6838467().run(); + } + + void run() throws Exception { + // on Windows, verify file system is not case significant + if (System.getProperty("os.name").toLowerCase().startsWith("windows") + && fileSystemIsCaseSignificant) { + error("fileSystemIsCaseSignificant is set on Windows."); + } + + // create a set of directories and zip files to compare + createTestDir(new File("dir"), paths); + createTestDir(new File("not_dir"), paths); + createTestZip(new File("zip"), paths); + createTestZip(new File("not_zip"), paths); + if (fileSystemIsCaseSignificant) { + createTestDir(new File("DIR"), paths); + createTestZip(new File("ZIP"), paths); + } + + // test the various sorts of file objects that can be obtained from + // the file manager, and for various values that may or may not match. + for (FileKind fk: FileKind.values()) { + for (CompareKind ck: CompareKind.values()) { + test(fk, ck); + } + } + + // verify that the various different types of file object were all + // tested + Set expectClasses = new HashSet(Arrays.asList( + "RegularFileObject", "ZipFileObject", "ZipFileIndexFileObject" )); + if (!foundClasses.equals(expectClasses)) { + error("expected fileobject classes not found\n" + + "expected: " + expectClasses + "\n" + + "found: " + foundClasses); + } + + if (errors > 0) + throw new Exception(errors + " errors"); + } + + void test(FileKind fk, CompareKind ck) throws IOException { + File f1 = fk.file; + JavaFileManager fm1 = createFileManager(fk, f1); + + File f2 = ck.other(fk.file); + JavaFileManager fm2 = createFileManager(fk, f2); + + try { + // If the directories or zip files match, we expect "n" matches in + // the "n-squared" comparisons to come, where "n" is the number of + // entries in the the directories or zip files. + // If the directories or zip files don't themselves match, + // we obviously don't expect any of their contents to match either. + int expect = (f1.getAbsoluteFile().equals(f2.getAbsoluteFile()) ? paths.length : 0); + + System.err.println("test " + (++count) + " " + fk + " " + ck + " " + f1 + " " + f2); + test(fm1, fm2, expect); + + } finally { + fm1.close(); + fm2.close(); + } + } + + // For a pair of file managers that may or may not have similar entries + // on the classpath, compare all files returned from one against all files + // returned from the other. For each pair of files, verify that if they + // are equal, the hashcode is equal as well, and finally verify that the + // expected number of matches was found. + void test(JavaFileManager fm1, JavaFileManager fm2, int expectEqualCount) throws IOException { + boolean foundFiles1 = false; + boolean foundFiles2 = false; + int foundEqualCount = 0; + Set kinds = EnumSet.allOf(JavaFileObject.Kind.class); + for (FileObject fo1: fm1.list(StandardLocation.CLASS_PATH, "p", kinds, false)) { + foundFiles1 = true; + foundClasses.add(fo1.getClass().getSimpleName()); + for (FileObject fo2: fm2.list(StandardLocation.CLASS_PATH, "p", kinds, false)) { + foundFiles2 = true; + foundClasses.add(fo1.getClass().getSimpleName()); + System.err.println("compare " + fo1 + " " + fo2); + if (fo1.equals(fo2)) { + foundEqualCount++; + int hash1 = fo1.hashCode(); + int hash2 = fo2.hashCode(); + if (hash1 != hash2) + error("hashCode error: " + fo1 + " [" + hash1 + "] " + + fo2 + " [" + hash2 + "]"); + } + } + } + if (!foundFiles1) + error("no files found for file manager 1"); + if (!foundFiles2) + error("no files found for file manager 2"); + // verify the expected number of matches were found + if (foundEqualCount != expectEqualCount) + error("expected matches not found: expected " + expectEqualCount + ", found " + foundEqualCount); + } + + // create a file manager to test a FileKind, with a given directory + // or zip file placed on the classpath + JavaFileManager createFileManager(FileKind fk, File classpath) throws IOException { + StandardJavaFileManager fm = createFileManager(fk == FileKind.ZIP); + fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(classpath)); + return fm; + } + + JavacFileManager createFileManager(boolean useJavaUtilZip) { + // javac should really not be using system properties like this + // -- it should really be using (hidden) options -- but until then + // take care to leave system properties as we find them, so as not + // to adversely affect other tests that might follow. + String prev = System.getProperty("useJavaUtilZip"); + boolean resetProperties = false; + try { + if (useJavaUtilZip) { + System.setProperty("useJavaUtilZip", "true"); + resetProperties = true; + } else if (System.getProperty("useJavaUtilZip") != null) { + System.getProperties().remove("useJavaUtilZip"); + resetProperties = true; + } + + Context c = new Context(); + return new JavacFileManager(c, false, null); + } finally { + if (resetProperties) { + if (prev == null) { + System.getProperties().remove("useJavaUtilZip"); + } else { + System.setProperty("useJavaUtilZip", prev); + } + } + } + } + + // create a directory containing a given set of paths + void createTestDir(File dir, String[] paths) throws IOException { + for (String p: paths) { + File file = new File(dir, p); + file.getParentFile().mkdirs(); + FileWriter out = new FileWriter(file); + try { + out.write(p); + } finally { + out.close(); + } + } + } + + // create a sip file containing a given set of entries + void createTestZip(File zip, String[] paths) throws IOException { + if (zip.getParentFile() != null) + zip.getParentFile().mkdirs(); + ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip)); + try { + for (String p: paths) { + ZipEntry ze = new ZipEntry(p); + zos.putNextEntry(ze); + byte[] bytes = p.getBytes(); + zos.write(bytes, 0, bytes.length); + zos.closeEntry(); + } + } finally { + zos.close(); + } + } + + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int count; + int errors; + Set foundClasses = new HashSet(); +} + From bb0ea6325cdabea9920f19124aa0530a21d6ae33 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 14 Oct 2009 18:56:37 -0700 Subject: [PATCH 055/172] 6558804: Specification for Elements.getDocComment(Element e) should be clarified Reviewed-by: jjg --- .../classes/javax/lang/model/util/Elements.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/langtools/src/share/classes/javax/lang/model/util/Elements.java b/langtools/src/share/classes/javax/lang/model/util/Elements.java index adeba608d6c..88743bb7a1e 100644 --- a/langtools/src/share/classes/javax/lang/model/util/Elements.java +++ b/langtools/src/share/classes/javax/lang/model/util/Elements.java @@ -77,9 +77,25 @@ public interface Elements { * Returns the text of the documentation ("Javadoc") * comment of an element. * + *

A documentation comment of an element is a comment that + * begins with "{@code /**}" , ends with a separate + * "*/", and immediately precedes the element, + * ignoring white space. Therefore, a documentation comment + * contains at least three"{@code *}" characters. The text + * returned for the documentation comment is a processed form of + * the comment as it appears in source code. The leading "{@code + * /**}" and trailing "*/" are removed. For lines + * of the comment starting after the initial "{@code /**}", + * leading white space characters are discarded as are any + * consecutive "{@code *}" characters appearing after the white + * space or starting the line. The processed lines are then + * concatenated together (including line terminators) and + * returned. + * * @param e the element being examined * @return the documentation comment of the element, or {@code null} * if there is none + * @jls3 3.6 White Space */ String getDocComment(Element e); From 6f42b7b834c71d0d2f4343d71717351e8986b10f Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Wed, 14 Oct 2009 20:16:02 -0700 Subject: [PATCH 056/172] 6891701: test/java/lang/management/RuntimeMXBean/GetSystemProperties should restore the system property Restore the system properties when the test finishes Reviewed-by: jjg --- .../RuntimeMXBean/GetSystemProperties.java | 20 ++++++++++++++++++- .../RuntimeMXBean/PropertiesTest.java | 19 +++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/jdk/test/java/lang/management/RuntimeMXBean/GetSystemProperties.java b/jdk/test/java/lang/management/RuntimeMXBean/GetSystemProperties.java index 6a324bfcd53..5a655378462 100644 --- a/jdk/test/java/lang/management/RuntimeMXBean/GetSystemProperties.java +++ b/jdk/test/java/lang/management/RuntimeMXBean/GetSystemProperties.java @@ -49,6 +49,21 @@ public class GetSystemProperties { private static final String VALUE4 = "test.property.value4"; public static void main(String[] argv) throws Exception { + // Save a copy of the original system properties + Properties props = System.getProperties(); + + try { + // replace the system Properties object for any modification + // in case jtreg caches a copy + System.setProperties(new Properties(props)); + runTest(); + } finally { + // restore original system properties + System.setProperties(props); + } + } + + private static void runTest() throws Exception { RuntimeMXBean mbean = ManagementFactory.getRuntimeMXBean(); // Print all system properties @@ -88,7 +103,10 @@ public class GetSystemProperties { Map props2 = mbean.getSystemProperties(); // expect the system properties returned should be // same as the one before adding KEY3 and KEY4 - props1.equals(props2); + if (!props1.equals(props2)) { + throw new RuntimeException("Two copies of system properties " + + "are expected to be equal"); + } System.out.println("Test passed."); } diff --git a/jdk/test/java/lang/management/RuntimeMXBean/PropertiesTest.java b/jdk/test/java/lang/management/RuntimeMXBean/PropertiesTest.java index 2900b3c3dfb..047f291dfbd 100644 --- a/jdk/test/java/lang/management/RuntimeMXBean/PropertiesTest.java +++ b/jdk/test/java/lang/management/RuntimeMXBean/PropertiesTest.java @@ -40,8 +40,21 @@ import java.lang.management.RuntimeMXBean; public class PropertiesTest { private static int NUM_MYPROPS = 3; public static void main(String[] argv) throws Exception { - Properties sysProps = System.getProperties(); + // Save a copy of the original system properties + Properties props = System.getProperties(); + try { + // replace the system Properties object for any modification + // in case jtreg caches a copy + System.setProperties(new Properties(props)); + runTest(props.size()); + } finally { + // restore original system properties + System.setProperties(props); + } + } + + private static void runTest(int sysPropsCount) throws Exception { // Create a new system properties using the old one // as the defaults Properties myProps = new Properties( System.getProperties() ); @@ -65,10 +78,10 @@ public class PropertiesTest { System.out.println(i++ + ": " + key + " : " + value); } - if (props.size() != NUM_MYPROPS + sysProps.size()) { + if (props.size() != NUM_MYPROPS + sysPropsCount) { throw new RuntimeException("Test Failed: " + "Expected number of properties = " + - NUM_MYPROPS + sysProps.size() + + NUM_MYPROPS + sysPropsCount + " but found = " + props.size()); } } From 347f6581ead9130d530ee541ffa99e315e4b2f96 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Thu, 15 Oct 2009 11:54:04 +0100 Subject: [PATCH 057/172] 6883983: JarVerifier dependency on sun.security.pkcs should be removed Reviewed-by: sherman, wetmore --- jdk/src/share/classes/java/util/jar/JarVerifier.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/jdk/src/share/classes/java/util/jar/JarVerifier.java b/jdk/src/share/classes/java/util/jar/JarVerifier.java index 54954413e59..099cf7abbb4 100644 --- a/jdk/src/share/classes/java/util/jar/JarVerifier.java +++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java @@ -293,10 +293,8 @@ class JarVerifier { } sfv.process(sigFileSigners); - } catch (sun.security.pkcs.ParsingException pe) { - if (debug != null) debug.println("processEntry caught: "+pe); - // ignore and treat as unsigned } catch (IOException ioe) { + // e.g. sun.security.pkcs.ParsingException if (debug != null) debug.println("processEntry caught: "+ioe); // ignore and treat as unsigned } catch (SignatureException se) { From d7441d877210ceecf16255fd042165b610ed1aef Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Thu, 15 Oct 2009 11:55:19 +0100 Subject: [PATCH 058/172] 6891404: (fs) ACL tests fail with "Invalid argument" on ZFS (sol) Reviewed-by: sherman --- .../sun/nio/fs/SolarisAclFileAttributeView.java | 10 +++++----- .../nio/file/attribute/AclFileAttributeView/Basic.java | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java index c576f968197..202efdad8cf 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java +++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java @@ -104,11 +104,11 @@ class SolarisAclFileAttributeView int uid; if (user.isSpecial()) { uid = -1; - if (who.getName().equals(UnixUserPrincipals.SPECIAL_OWNER.getName())) + if (who == UnixUserPrincipals.SPECIAL_OWNER) flags |= ACE_OWNER; - else if (who.getName().equals(UnixUserPrincipals.SPECIAL_GROUP.getName())) - flags |= ACE_GROUP; - else if (who.getName().equals(UnixUserPrincipals.SPECIAL_EVERYONE.getName())) + else if (who == UnixUserPrincipals.SPECIAL_GROUP) + flags |= (ACE_GROUP | ACE_IDENTIFIER_GROUP); + else if (who == UnixUserPrincipals.SPECIAL_EVERYONE) flags |= ACE_EVERYONE; else throw new AssertionError("Unable to map special identifier"); @@ -281,7 +281,7 @@ class SolarisAclFileAttributeView aceFlags.add(AclEntryFlag.DIRECTORY_INHERIT); if ((flags & ACE_NO_PROPAGATE_INHERIT_ACE) > 0) aceFlags.add(AclEntryFlag.NO_PROPAGATE_INHERIT); - if ((flags & ACE_INHERIT_ONLY_ACE ) > 0) + if ((flags & ACE_INHERIT_ONLY_ACE) > 0) aceFlags.add(AclEntryFlag.INHERIT_ONLY); // build the ACL entry and add it to the list diff --git a/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java b/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java index 14563202bd8..3b8a8bc2f82 100644 --- a/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java +++ b/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6838333 + * @bug 4313887 6838333 6891404 * @summary Unit test for java.nio.file.attribute.AclFileAttribueView * @library ../.. */ From 31f813d99e880ef04844dcbb8bede01f0905dabf Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Thu, 15 Oct 2009 12:03:31 +0100 Subject: [PATCH 059/172] 6886436: Lightwight HTTP Container (com.sun.* package) is unstable Reviewed-by: chegar --- .../sun/net/httpserver/ExchangeImpl.java | 16 ++++ .../www/protocol/http/HttpURLConnection.java | 4 + .../com/sun/net/httpserver/bugs/B6886436.java | 93 +++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 jdk/test/com/sun/net/httpserver/bugs/B6886436.java diff --git a/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java b/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java index f15a3d0d573..ccb9151b69c 100644 --- a/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java +++ b/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java @@ -31,6 +31,7 @@ import java.nio.channels.*; import java.net.*; import javax.net.ssl.*; import java.util.*; +import java.util.logging.Logger; import java.text.*; import sun.net.www.MessageHeader; import com.sun.net.httpserver.*; @@ -204,6 +205,21 @@ class ExchangeImpl { tmpout.write (bytes(statusLine, 0), 0, statusLine.length()); boolean noContentToSend = false; // assume there is content rspHdrs.set ("Date", df.format (new Date())); + + /* check for response type that is not allowed to send a body */ + + if ((rCode>=100 && rCode <200) /* informational */ + ||(rCode == 204) /* no content */ + ||(rCode == 304)) /* not modified */ + { + if (contentLen != -1) { + Logger logger = server.getLogger(); + String msg = "sendResponseHeaders: rCode = "+ rCode + + ": forcing contentLen = -1"; + logger.warning (msg); + } + contentLen = -1; + } if (contentLen == 0) { if (http10) { o.setWrappedStream (new UndefLengthOutputStream (this, ros)); diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index f1a60f85fe3..c872526e597 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -1180,6 +1180,10 @@ public class HttpURLConnection extends java.net.HttpURLConnection { inputStream = http.getInputStream(); respCode = getResponseCode(); + if (respCode == -1) { + disconnectInternal(); + throw new IOException ("Invalid Http response"); + } if (respCode == HTTP_PROXY_AUTH) { if (streaming()) { disconnectInternal(); diff --git a/jdk/test/com/sun/net/httpserver/bugs/B6886436.java b/jdk/test/com/sun/net/httpserver/bugs/B6886436.java new file mode 100644 index 00000000000..2653ae7be85 --- /dev/null +++ b/jdk/test/com/sun/net/httpserver/bugs/B6886436.java @@ -0,0 +1,93 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6886436 + * @summary + */ + +import com.sun.net.httpserver.*; + +import java.util.*; +import java.util.concurrent.*; +import java.util.logging.*; +import java.io.*; +import java.net.*; + +public class B6886436 { + + public static void main (String[] args) throws Exception { + Logger logger = Logger.getLogger ("com.sun.net.httpserver"); + ConsoleHandler c = new ConsoleHandler(); + c.setLevel (Level.WARNING); + logger.addHandler (c); + logger.setLevel (Level.WARNING); + Handler handler = new Handler(); + InetSocketAddress addr = new InetSocketAddress (0); + HttpServer server = HttpServer.create (addr, 0); + HttpContext ctx = server.createContext ("/test", handler); + ExecutorService executor = Executors.newCachedThreadPool(); + server.setExecutor (executor); + server.start (); + + URL url = new URL ("http://localhost:"+server.getAddress().getPort()+"/test/foo.html"); + HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); + try { + InputStream is = urlc.getInputStream(); + while (is.read()!= -1) ; + is.close (); + urlc = (HttpURLConnection)url.openConnection (); + urlc.setReadTimeout (3000); + is = urlc.getInputStream(); + while (is.read()!= -1); + is.close (); + + } catch (IOException e) { + server.stop(2); + executor.shutdown(); + throw new RuntimeException ("Test failed"); + } + server.stop(2); + executor.shutdown(); + System.out.println ("OK"); + } + + public static boolean error = false; + + static class Handler implements HttpHandler { + int invocation = 1; + public void handle (HttpExchange t) + throws IOException + { + InputStream is = t.getRequestBody(); + Headers map = t.getRequestHeaders(); + Headers rmap = t.getResponseHeaders(); + while (is.read () != -1) ; + is.close(); + // send a 204 response with an empty chunked body + t.sendResponseHeaders (204, 0); + t.close(); + } + } +} From e30aafe421f4fc7002b05790869c687fc404ceef Mon Sep 17 00:00:00 2001 From: Gary Benson Date: Thu, 15 Oct 2009 13:26:17 +0100 Subject: [PATCH 060/172] 6891677: java/build integrate zero assembler JDK changes Build changes for the Zero assembler port Reviewed-by: ohair, tbell --- make/hotspot-rules.gmk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/make/hotspot-rules.gmk b/make/hotspot-rules.gmk index b99ffb79f93..481b91f1a52 100644 --- a/make/hotspot-rules.gmk +++ b/make/hotspot-rules.gmk @@ -72,6 +72,10 @@ ifeq ($(DEBUG_NAME), fastdebug) HOTSPOT_TARGET = all_fastdebug endif +ifeq ($(ZERO_BUILD), true) + HOTSPOT_TARGET := $(HOTSPOT_TARGET)zero +endif + HOTSPOT_BUILD_ARGUMENTS += $(COMMON_BUILD_ARGUMENTS) HOTSPOT_BUILD_ARGUMENTS += ALT_OUTPUTDIR=$(HOTSPOT_OUTPUTDIR) HOTSPOT_BUILD_ARGUMENTS += ALT_EXPORT_PATH=$(HOTSPOT_EXPORT_PATH) From c83af332056090f02946002b147ef5fa656c0048 Mon Sep 17 00:00:00 2001 From: Gary Benson Date: Thu, 15 Oct 2009 13:27:59 +0100 Subject: [PATCH 061/172] 6891677: java/build integrate zero assembler JDK changes Build changes for the Zero assembler port Reviewed-by: ohair, tbell --- jdk/make/common/Defs-linux.gmk | 14 +++- jdk/make/common/Program.gmk | 12 ++- jdk/make/java/instrument/Makefile | 2 +- jdk/make/java/jli/Makefile | 4 + jdk/make/java/redist/Makefile | 7 +- jdk/make/javax/sound/SoundDefs.gmk | 28 ++++--- jdk/make/jdk_generic_profile.sh | 79 +++++++++++++++++++ .../native/com/sun/media/sound/SoundDefs.h | 1 + jdk/src/solaris/bin/ergo_zero.c | 58 ++++++++++++++ jdk/src/solaris/bin/zero/jvm.cfg | 39 +++++++++ 10 files changed, 224 insertions(+), 20 deletions(-) create mode 100644 jdk/src/solaris/bin/ergo_zero.c create mode 100644 jdk/src/solaris/bin/zero/jvm.cfg diff --git a/jdk/make/common/Defs-linux.gmk b/jdk/make/common/Defs-linux.gmk index 5cd9d9222f8..f1efcefd0a6 100644 --- a/jdk/make/common/Defs-linux.gmk +++ b/jdk/make/common/Defs-linux.gmk @@ -116,8 +116,16 @@ CFLAGS_REQUIRED_sparcv9 += -m64 -mcpu=v9 LDFLAGS_COMMON_sparcv9 += -m64 -mcpu=v9 CFLAGS_REQUIRED_sparc += -m32 -mcpu=v9 LDFLAGS_COMMON_sparc += -m32 -mcpu=v9 -CFLAGS_REQUIRED = $(CFLAGS_REQUIRED_$(ARCH)) -LDFLAGS_COMMON += $(LDFLAGS_COMMON_$(ARCH)) +ifeq ($(ZERO_BUILD), true) + CFLAGS_REQUIRED = $(ZERO_ARCHFLAG) + ifeq ($(ZERO_ENDIANNESS), little) + CFLAGS_REQUIRED += -D_LITTLE_ENDIAN + endif + LDFLAGS_COMMON += $(ZERO_ARCHFLAG) +else + CFLAGS_REQUIRED = $(CFLAGS_REQUIRED_$(ARCH)) + LDFLAGS_COMMON += $(LDFLAGS_COMMON_$(ARCH)) +endif # If this is a --hash-style=gnu system, use --hash-style=both # The gnu .hash section won't work on some Linux systems like SuSE 10. @@ -217,7 +225,7 @@ endif EXTRA_LIBS += -lc -LDFLAGS_DEFS_OPTION = -z defs +LDFLAGS_DEFS_OPTION = -Xlinker -z -Xlinker defs LDFLAGS_COMMON += $(LDFLAGS_DEFS_OPTION) # diff --git a/jdk/make/common/Program.gmk b/jdk/make/common/Program.gmk index 067ffa39b9e..cb4fe13ee84 100644 --- a/jdk/make/common/Program.gmk +++ b/jdk/make/common/Program.gmk @@ -85,7 +85,7 @@ ifneq (,$(findstring $(PLATFORM), linux solaris)) # UNIX systems endif endif ifeq ($(PLATFORM), linux) - LDFLAGS += -z origin + LDFLAGS += -Wl,-z -Wl,origin LDFLAGS += -Wl,--allow-shlib-undefined LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../lib/$(LIBARCH)/jli LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../jre/lib/$(LIBARCH)/jli @@ -279,8 +279,14 @@ $(OBJDIR)/main.$(OBJECT_SUFFIX): $(LAUNCHER_SHARE_SRC)/bin/main.c # # How to install jvm.cfg. -# -$(JVMCFG): $(LAUNCHER_PLATFORM_SRC)/bin/$(ARCH)/jvm.cfg +# +ifeq ($(ZERO_BUILD), true) +JVMCFG_ARCH = zero +else +JVMCFG_ARCH = $(ARCH) +endif + +$(JVMCFG): $(LAUNCHER_PLATFORM_SRC)/bin/$(JVMCFG_ARCH)/jvm.cfg $(install-file) # diff --git a/jdk/make/java/instrument/Makefile b/jdk/make/java/instrument/Makefile index 646fcdc6f34..f46b3d10cc1 100644 --- a/jdk/make/java/instrument/Makefile +++ b/jdk/make/java/instrument/Makefile @@ -109,7 +109,7 @@ else LDFLAGS += -R \$$ORIGIN/jli endif ifeq ($(PLATFORM), linux) - LDFLAGS += -z origin + LDFLAGS += -Wl,-z -Wl,origin LDFLAGS += -Wl,--allow-shlib-undefined LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/jli endif diff --git a/jdk/make/java/jli/Makefile b/jdk/make/java/jli/Makefile index 7f972f16031..861d5375e92 100644 --- a/jdk/make/java/jli/Makefile +++ b/jdk/make/java/jli/Makefile @@ -48,11 +48,15 @@ ZIP_SRC = $(SHARE_SRC)/native/java/util/zip/zlib-$(ZLIB_VERSION) LAUNCHER_SHARE_SRC = $(SHARE_SRC)/bin LAUNCHER_PLATFORM_SRC = $(PLATFORM_SRC)/bin +ifeq ($(ZERO_BUILD), true) +ERGO_FAMILY=zero +else ifeq ($(ARCH_FAMILY), amd64) ERGO_FAMILY=i586 else ERGO_FAMILY=$(ARCH_FAMILY) endif +endif # diff --git a/jdk/make/java/redist/Makefile b/jdk/make/java/redist/Makefile index 0d32cd141dc..45b179cd976 100644 --- a/jdk/make/java/redist/Makefile +++ b/jdk/make/java/redist/Makefile @@ -94,11 +94,13 @@ ifeq ($(INCLUDE_SA), true) endif endif # INCLUDE_SA -# Hotspot client is only available on 32-bit builds +# Hotspot client is only available on 32-bit non-Zero builds +ifneq ($(ZERO_BUILD), true) ifeq ($(ARCH_DATA_MODEL), 32) IMPORT_LIST += $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_NAME) \ $(LIB_LOCATION)/$(CLIENT_LOCATION)/Xusage.txt endif +endif ifeq ($(PLATFORM), windows) # Windows vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Windows @@ -171,6 +173,7 @@ ifeq ($(PLATFORM), solaris) IMPORT_LIST += $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDB_NAME) endif +ifneq ($(ZERO_BUILD), true) ifeq ($(ARCH_DATA_MODEL), 32) IMPORT_LIST += $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(LIBJSIG_NAME) @@ -201,6 +204,8 @@ endif # 32bit solaris endif # 32bit +endif # ZERO_BUILD + # NOT Windows ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ NOT Windows endif # PLATFORM diff --git a/jdk/make/javax/sound/SoundDefs.gmk b/jdk/make/javax/sound/SoundDefs.gmk index 93dfdf46e6a..dd650010369 100644 --- a/jdk/make/javax/sound/SoundDefs.gmk +++ b/jdk/make/javax/sound/SoundDefs.gmk @@ -55,21 +55,25 @@ ifeq ($(PLATFORM), solaris) endif # PLATFORM solaris -ifeq ($(ARCH), i586) - CPPFLAGS += -DX_ARCH=X_I586 -endif # ARCH i586 +ifeq ($(ZERO_BUILD), true) + CPPFLAGS += -DX_ARCH=X_ZERO +else + ifeq ($(ARCH), i586) + CPPFLAGS += -DX_ARCH=X_I586 + endif # ARCH i586 -ifeq ($(ARCH), sparc) - CPPFLAGS += -DX_ARCH=X_SPARC -endif # ARCH sparc + ifeq ($(ARCH), sparc) + CPPFLAGS += -DX_ARCH=X_SPARC + endif # ARCH sparc -ifeq ($(ARCH), sparcv9) - CPPFLAGS += -DX_ARCH=X_SPARCV9 -endif # ARCH sparcv9 + ifeq ($(ARCH), sparcv9) + CPPFLAGS += -DX_ARCH=X_SPARCV9 + endif # ARCH sparcv9 -ifeq ($(ARCH), amd64) - CPPFLAGS += -DX_ARCH=X_AMD64 -endif # ARCH amd64 + ifeq ($(ARCH), amd64) + CPPFLAGS += -DX_ARCH=X_AMD64 + endif # ARCH amd64 +endif # files needed for MIDI i/o diff --git a/jdk/make/jdk_generic_profile.sh b/jdk/make/jdk_generic_profile.sh index 125198301ca..66d46bc287f 100644 --- a/jdk/make/jdk_generic_profile.sh +++ b/jdk/make/jdk_generic_profile.sh @@ -339,3 +339,82 @@ fi PATH="${path4sdk}" export PATH +# Export variables required for Zero +if [ "${ZERO_BUILD}" = true ] ; then + # ZERO_LIBARCH is the name of the architecture-specific + # subdirectory under $JAVA_HOME/jre/lib + arch=$(uname -m) + case "${arch}" in + x86_64) ZERO_LIBARCH=amd64 ;; + i?86) ZERO_LIBARCH=i386 ;; + sparc64) ZERO_LIBARCH=sparcv9 ;; + arm*) ZERO_LIBARCH=arm ;; + *) ZERO_LIBARCH="$(arch)" + esac + export ZERO_LIBARCH + + # ARCH_DATA_MODEL is the number of bits in a pointer + case "${ZERO_LIBARCH}" in + i386|ppc|s390|sparc|arm) + ARCH_DATA_MODEL=32 + ;; + amd64|ppc64|s390x|sparcv9|ia64|alpha) + ARCH_DATA_MODEL=64 + ;; + *) + echo "ERROR: Unable to determine ARCH_DATA_MODEL for ${ZERO_LIBARCH}" + exit 1 + esac + export ARCH_DATA_MODEL + + # ZERO_ENDIANNESS is the endianness of the processor + case "${ZERO_LIBARCH}" in + i386|amd64|ia64) + ZERO_ENDIANNESS=little + ;; + ppc*|s390*|sparc*|alpha) + ZERO_ENDIANNESS=big + ;; + *) + echo "ERROR: Unable to determine ZERO_ENDIANNESS for ${ZERO_LIBARCH}" + exit 1 + esac + export ZERO_ENDIANNESS + + # ZERO_ARCHDEF is used to enable architecture-specific code + case "${ZERO_LIBARCH}" in + i386) ZERO_ARCHDEF=IA32 ;; + ppc*) ZERO_ARCHDEF=PPC ;; + s390*) ZERO_ARCHDEF=S390 ;; + sparc*) ZERO_ARCHDEF=SPARC ;; + *) ZERO_ARCHDEF=$(echo "${ZERO_LIBARCH}" | tr a-z A-Z) + esac + export ZERO_ARCHDEF + + # ZERO_ARCHFLAG tells the compiler which mode to build for + case "${ZERO_LIBARCH}" in + s390) + ZERO_ARCHFLAG="-m31" + ;; + *) + ZERO_ARCHFLAG="-m${ARCH_DATA_MODEL}" + esac + export ZERO_ARCHFLAG + + # LIBFFI_CFLAGS and LIBFFI_LIBS tell the compiler how to compile and + # link against libffi + pkgconfig=$(which pkg-config 2>/dev/null) + if [ -x "${pkgconfig}" ] ; then + if [ "${LIBFFI_CFLAGS}" = "" ] ; then + LIBFFI_CFLAGS=$("${pkgconfig}" --cflags libffi) + fi + if [ "${LIBFFI_LIBS}" = "" ] ; then + LIBFFI_LIBS=$("${pkgconfig}" --libs libffi) + fi + fi + if [ "${LIBFFI_LIBS}" = "" ] ; then + LIBFFI_LIBS="-lffi" + fi + export LIBFFI_CFLAGS + export LIBFFI_LIBS +fi diff --git a/jdk/src/share/native/com/sun/media/sound/SoundDefs.h b/jdk/src/share/native/com/sun/media/sound/SoundDefs.h index 893dacf3e55..13dd33d4715 100644 --- a/jdk/src/share/native/com/sun/media/sound/SoundDefs.h +++ b/jdk/src/share/native/com/sun/media/sound/SoundDefs.h @@ -38,6 +38,7 @@ #define X_SPARCV9 3 #define X_IA64 4 #define X_AMD64 5 +#define X_ZERO 6 // ********************************** // Make sure you set X_PLATFORM and X_ARCH defines correctly. diff --git a/jdk/src/solaris/bin/ergo_zero.c b/jdk/src/solaris/bin/ergo_zero.c new file mode 100644 index 00000000000..3bf541444ca --- /dev/null +++ b/jdk/src/solaris/bin/ergo_zero.c @@ -0,0 +1,58 @@ +/* + * Copyright 1998-2007 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +#include "ergo.h" + + +/* Methods for solaris-sparc and linux-sparc: these are easy. */ + +/* Ask the OS how many processors there are. */ +static unsigned long +physical_processors(void) { + const unsigned long sys_processors = sysconf(_SC_NPROCESSORS_CONF); + + JLI_TraceLauncher("sysconf(_SC_NPROCESSORS_CONF): %lu\n", sys_processors); + return sys_processors; +} + +/* The sparc version of the "server-class" predicate. */ +jboolean +ServerClassMachineImpl(void) { + jboolean result = JNI_FALSE; + /* How big is a server class machine? */ + const unsigned long server_processors = 2UL; + const uint64_t server_memory = 2UL * GB; + const uint64_t actual_memory = physical_memory(); + + /* Is this a server class machine? */ + if (actual_memory >= server_memory) { + const unsigned long actual_processors = physical_processors(); + if (actual_processors >= server_processors) { + result = JNI_TRUE; + } + } + JLI_TraceLauncher("unix_" LIBARCHNAME "_ServerClassMachine: %s\n", + (result == JNI_TRUE ? "JNI_TRUE" : "JNI_FALSE")); + return result; +} diff --git a/jdk/src/solaris/bin/zero/jvm.cfg b/jdk/src/solaris/bin/zero/jvm.cfg new file mode 100644 index 00000000000..e4cea1c357b --- /dev/null +++ b/jdk/src/solaris/bin/zero/jvm.cfg @@ -0,0 +1,39 @@ +# Copyright 2003 Sun Microsystems, 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. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# +# +# List of JVMs that can be used as an option to java, javac, etc. +# Order is important -- first in this list is the default JVM. +# NOTE that this both this file and its format are UNSUPPORTED and +# WILL GO AWAY in a future release. +# +# You may also select a JVM in an arbitrary location with the +# "-XXaltjvm=" option, but that too is unsupported +# and may not be available in a future release. +# +-server KNOWN +-client IGNORE +-hotspot ERROR +-classic WARN +-native ERROR +-green ERROR From c45a788c5ca4ae0eaddd87c2c7d7f49de46816cf Mon Sep 17 00:00:00 2001 From: Gary Benson Date: Thu, 15 Oct 2009 13:28:26 +0100 Subject: [PATCH 062/172] 6891677: java/build integrate zero assembler JDK changes Build changes for the Zero assembler port Reviewed-by: ohair, tbell --- corba/make/common/Defs-linux.gmk | 14 +++++++++++--- corba/make/common/shared/Compiler-gcc.gmk | 6 ++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/corba/make/common/Defs-linux.gmk b/corba/make/common/Defs-linux.gmk index a8ad4c354bc..46a965e16ea 100644 --- a/corba/make/common/Defs-linux.gmk +++ b/corba/make/common/Defs-linux.gmk @@ -99,8 +99,16 @@ CFLAGS_REQUIRED_sparcv9 += -m64 -mcpu=v9 LDFLAGS_COMMON_sparcv9 += -m64 -mcpu=v9 CFLAGS_REQUIRED_sparc += -m32 -mcpu=v9 LDFLAGS_COMMON_sparc += -m32 -mcpu=v9 -CFLAGS_REQUIRED = $(CFLAGS_REQUIRED_$(ARCH)) -LDFLAGS_COMMON += $(LDFLAGS_COMMON_$(ARCH)) +ifeq ($(ZERO_BUILD), true) + CFLAGS_REQUIRED = $(ZERO_ARCHFLAG) + ifeq ($(ZERO_ENDIANNESS), little) + CFLAGS_REQUIRED += -D_LITTLE_ENDIAN + endif + LDFLAGS_COMMON += $(ZERO_ARCHFLAG) +else + CFLAGS_REQUIRED = $(CFLAGS_REQUIRED_$(ARCH)) + LDFLAGS_COMMON += $(LDFLAGS_COMMON_$(ARCH)) +endif # Add in platform specific optimizations for all opt levels CC_HIGHEST_OPT += $(_OPT_$(ARCH)) @@ -196,7 +204,7 @@ endif EXTRA_LIBS += -lc -LDFLAGS_DEFS_OPTION = -z defs +LDFLAGS_DEFS_OPTION = -Xlinker -z -Xlinker defs LDFLAGS_COMMON += $(LDFLAGS_DEFS_OPTION) # diff --git a/corba/make/common/shared/Compiler-gcc.gmk b/corba/make/common/shared/Compiler-gcc.gmk index 5fc30edb995..92c1be2697c 100644 --- a/corba/make/common/shared/Compiler-gcc.gmk +++ b/corba/make/common/shared/Compiler-gcc.gmk @@ -70,6 +70,11 @@ ifeq ($(PLATFORM), linux) else CXX = $(COMPILER_PATH)g++ endif + ifeq ($(ZERO_BUILD), true) + # zero + REQUIRED_CC_VER = 3.2 + REQUIRED_GCC_VER = 3.2.* + else ifneq ("$(findstring sparc,$(ARCH))", "") # sparc or sparcv9 REQUIRED_CC_VER = 4.0 @@ -88,6 +93,7 @@ ifeq ($(PLATFORM), linux) endif endif endif + endif # Option used to create a shared library SHARED_LIBRARY_FLAG = -shared -mimpure-text SUN_COMP_VER := $(shell $(CC) --verbose 2>&1 ) From 8eace255e1863037b5c781144f380c14e62d2771 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Thu, 15 Oct 2009 11:47:13 -0700 Subject: [PATCH 063/172] 6891750: deopt blob kills values in O5 Reviewed-by: kvn, twisti --- .../src/cpu/sparc/vm/sharedRuntime_sparc.cpp | 20 ++-- .../test/compiler/6891750/Test6891750.java | 108 ++++++++++++++++++ 2 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 hotspot/test/compiler/6891750/Test6891750.java diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index f4063e128e4..19cd413d043 100644 --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -3213,9 +3213,8 @@ void SharedRuntime::generate_deopt_blob() { Register Oreturn0 = O0; Register Oreturn1 = O1; Register O2UnrollBlock = O2; - Register O3tmp = O3; - Register I5exception_tmp = I5; - Register G4exception_tmp = G4_scratch; + Register L0deopt_mode = L0; + Register G4deopt_mode = G4_scratch; int frame_size_words; Address saved_Freturn0_addr(FP, -sizeof(double) + STACK_BIAS); #if !defined(_LP64) && defined(COMPILER2) @@ -3265,7 +3264,7 @@ void SharedRuntime::generate_deopt_blob() { map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words); __ ba(false, cont); - __ delayed()->mov(Deoptimization::Unpack_deopt, I5exception_tmp); + __ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode); int exception_offset = __ offset() - start; @@ -3316,7 +3315,7 @@ void SharedRuntime::generate_deopt_blob() { #endif __ ba(false, cont); - __ delayed()->mov(Deoptimization::Unpack_exception, I5exception_tmp);; + __ delayed()->mov(Deoptimization::Unpack_exception, L0deopt_mode);; // // Reexecute entry, similar to c2 uncommon trap @@ -3326,7 +3325,7 @@ void SharedRuntime::generate_deopt_blob() { // No need to update oop_map as each call to save_live_registers will produce identical oopmap (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words); - __ mov(Deoptimization::Unpack_reexecute, I5exception_tmp); + __ mov(Deoptimization::Unpack_reexecute, L0deopt_mode); __ bind(cont); @@ -3349,14 +3348,14 @@ void SharedRuntime::generate_deopt_blob() { // NOTE: we know that only O0/O1 will be reloaded by restore_result_registers // so this move will survive - __ mov(I5exception_tmp, G4exception_tmp); + __ mov(L0deopt_mode, G4deopt_mode); __ mov(O0, O2UnrollBlock->after_save()); RegisterSaver::restore_result_registers(masm); Label noException; - __ cmp(G4exception_tmp, Deoptimization::Unpack_exception); // Was exception pending? + __ cmp(G4deopt_mode, Deoptimization::Unpack_exception); // Was exception pending? __ br(Assembler::notEqual, false, Assembler::pt, noException); __ delayed()->nop(); @@ -3390,10 +3389,10 @@ void SharedRuntime::generate_deopt_blob() { } #endif __ set_last_Java_frame(SP, noreg); - __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, G4exception_tmp); + __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, G4deopt_mode); #else // LP64 uses g4 in set_last_Java_frame - __ mov(G4exception_tmp, O1); + __ mov(G4deopt_mode, O1); __ set_last_Java_frame(SP, G0); __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, O1); #endif @@ -3446,7 +3445,6 @@ void SharedRuntime::generate_uncommon_trap_blob() { #endif MacroAssembler* masm = new MacroAssembler(&buffer); Register O2UnrollBlock = O2; - Register O3tmp = O3; Register O2klass_index = O2; // diff --git a/hotspot/test/compiler/6891750/Test6891750.java b/hotspot/test/compiler/6891750/Test6891750.java new file mode 100644 index 00000000000..cb98f7249d1 --- /dev/null +++ b/hotspot/test/compiler/6891750/Test6891750.java @@ -0,0 +1,108 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +/** + * @test + * @bug 6891750 + * @summary deopt blob kills values in O5 + * + * @run main Test6891750 + */ + +abstract class Base6891750 extends Thread { + abstract public long m(); +} +class Other6891750 extends Base6891750 { + public long m() { + return 0; + } +} + +public class Test6891750 extends Base6891750 { + Base6891750 d; + volatile long value = 9; + + static int limit = 400000; + + Test6891750() { + d = this; + + } + public long m() { + return value; + } + + public long test(boolean doit) { + if (doit) { + long total0 = 0; + long total1 = 0; + long total2 = 0; + long total3 = 0; + long total4 = 0; + long total5 = 0; + long total6 = 0; + long total7 = 0; + long total8 = 0; + long total9 = 0; + for (int i = 0; i < limit; i++) { + total0 += d.m(); + total1 += d.m(); + total2 += d.m(); + total3 += d.m(); + total4 += d.m(); + total5 += d.m(); + total6 += d.m(); + total7 += d.m(); + total8 += d.m(); + total9 += d.m(); + } + return total0 + total1 + total2 + total3 + total4 + total5 + total6 + total7 + total8 + total9; + } + return 0; + } + + public void run() { + long result = test(true); + for (int i = 0; i < 300; i++) { + long result2 = test(true); + if (result != result2) { + throw new InternalError(result + " != " + result2); + } + } + } + + public static void main(String[] args) throws Exception { + Test6891750 Test6891750 = new Test6891750(); + // warm it up + for (int i = 0; i < 200000; i++) { + Test6891750.test(false); + } + // set in off running + Test6891750.start(); + Thread.sleep(2000); + + // Load a class to invalidate CHA + new Other6891750(); + } +} From cd806fb89cd75104567189736c4176befbac7b0f Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 15 Oct 2009 16:40:15 -0700 Subject: [PATCH 064/172] Added tag jdk7-b74 for changeset e8f92456bc49 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 4511932e4a5..16a4362dac7 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -48,3 +48,4 @@ e1b972ff53cd58f825791f8ed9b2deffd16e768c jdk7-b68 4c36e9853dda27bdac5ef4839a610509fbe31d34 jdk7-b71 0d7e03b426df27c21dcc44ffb9178eacd1b04f10 jdk7-b72 3ac6dcf7823205546fbbc3d4ea59f37358d0b0d4 jdk7-b73 +2c88089b6e1c053597418099a14232182c387edc jdk7-b74 From 7917e7916c9a683cdb82e37b50739e2b21be3d42 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 15 Oct 2009 16:40:16 -0700 Subject: [PATCH 065/172] Added tag jdk7-b74 for changeset 2a58cc6c4797 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index d5a056ab705..8ec093cf9c3 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -48,3 +48,4 @@ a12ea7c7b497b4ba7830550095ef633bd6f43971 jdk7-b67 3f1ef7f899ea2aec189c4fb67e5c8fa374437c50 jdk7-b71 c793a31209263fbb867c23c752599d85c21abb73 jdk7-b72 b751c528c55560cf2adeaeef24b39ca1f4d1cbf7 jdk7-b73 +5d0cf59a3203b9f57aceebc33ae656b884987955 jdk7-b74 From 89510f5c0bdf5380f57efd454297881acb1bf567 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 15 Oct 2009 16:40:19 -0700 Subject: [PATCH 066/172] Added tag jdk7-b74 for changeset b95ea007fe67 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 92383ca276a..76fc22cd617 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -48,3 +48,4 @@ d07e68298d4e17ebf93d8299e43fcc3ded26472a jdk7-b68 50a95aa4a247f0cbbf66df285a8b1d78ffb153d9 jdk7-b71 a94714c550658fd6741793ef036cb9625dc2ab1a jdk7-b72 faf94d94786b621f8e13cbcc941ca69c6d967c3f jdk7-b73 +f4b900403d6e4b0af51447bd13bbe23fe3a1dac7 jdk7-b74 From ebfdb19605256bbeb11fd10e7a2b5c41f97845a5 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 15 Oct 2009 16:40:25 -0700 Subject: [PATCH 067/172] Added tag jdk7-b74 for changeset 73df4e30ad5a --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index f9500dfdb66..a840b3ac5ea 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -48,3 +48,4 @@ c83f0106b78a85c7e614d27a328675460b2081cf jdk7-b70 ff94d8ce0daded647bb326630e643d010357afce jdk7-b71 37c805b6156fd492c12301688b54a6bcca39e729 jdk7-b72 feb05980f9f2964e6bc2b3a8532f9b3054c2289b jdk7-b73 +ea7b88c676dd8b269bc858a4a17c14dc96c8aed1 jdk7-b74 From bf385caedb6cfd9fa125814c9f843140588d3b6e Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 15 Oct 2009 16:40:27 -0700 Subject: [PATCH 068/172] Added tag jdk7-b74 for changeset 4fb4f2670583 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 426d82a99b4..ecbc1811a5f 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -48,3 +48,4 @@ dd3c5f3ec28d5d5e5c0dc3229fdd52d85d04274d jdk7-b70 03314cf56a7212bbb6c186dbc9f15aca988a48ec jdk7-b71 4c990aa99bc037fd81dd1b1b269690e9bea8a0b4 jdk7-b72 558985e26fe16f5a6ebb2edb9180a42e1c8e8202 jdk7-b73 +f4466e1b608088c90e11beaa4b600f102608c6a1 jdk7-b74 From 66b96c7d3fec412e91d16263f7e725287ff4d5c1 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 15 Oct 2009 16:40:33 -0700 Subject: [PATCH 069/172] Added tag jdk7-b74 for changeset 6bab93485a15 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index edcf31c99c5..8c3ca49faa6 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -48,3 +48,4 @@ b23d905cb5d3b382295240d28ab0bfb266b4503c jdk7-b68 b3f3240135f0c10b9f2481c174b81b7fcf0daa60 jdk7-b71 460639b036f327282832a4fe52b7aa45688afd50 jdk7-b72 f708138c9aca4b389872838fe6773872fce3609e jdk7-b73 +eacb36e30327e7ae33baa068e82ddccbd91eaae2 jdk7-b74 From d6388ffec985e084bfa9e4516225b9153d8ff725 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 15 Oct 2009 16:40:44 -0700 Subject: [PATCH 070/172] Added tag jdk7-b74 for changeset 17d415c7180f --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index c7be42cd2b4..18494d5f934 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -48,3 +48,4 @@ ce9bcdcb7859bb7ef10afd078ad59ba7847f208d jdk7-b69 33c8c38e1757006c17d80499fb3347102501fae5 jdk7-b71 261c54b2312ed26d6ec45c675831375460250519 jdk7-b72 9596dff460935f09684c11d156ce591f92584f0d jdk7-b73 +1a66b08deed0459054b5b1bea3dfbead30d258fa jdk7-b74 From 9c1ea09b0727415a87fc961c3aaea6297afbe7ec Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Thu, 15 Oct 2009 17:36:53 -0700 Subject: [PATCH 071/172] 6891707: Eliminate the java.io.FilePermission dependency on PolicyFile Replace call to PolicyFile.canonPath with its own implementation Reviewed-by: alanb, mullan --- jdk/src/share/classes/java/io/FilePermission.java | 12 +++++++++++- .../classes/sun/security/provider/PolicyFile.java | 5 +++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/java/io/FilePermission.java b/jdk/src/share/classes/java/io/FilePermission.java index 88c98fbddf3..aeab68b7907 100644 --- a/jdk/src/share/classes/java/io/FilePermission.java +++ b/jdk/src/share/classes/java/io/FilePermission.java @@ -209,7 +209,17 @@ public final class FilePermission extends Permission implements Serializable { cpath = AccessController.doPrivileged(new PrivilegedAction() { public String run() { try { - return sun.security.provider.PolicyFile.canonPath(cpath); + String path = cpath; + if (cpath.endsWith("*")) { + // call getCanonicalPath with a path with wildcard character + // replaced to avoid calling it with paths that are + // intended to match all entries in a directory + path = path.substring(0, path.length()-1) + "-"; + path = new File(path).getCanonicalPath(); + return path.substring(0, path.length()-1) + "*"; + } else { + return new File(path).getCanonicalPath(); + } } catch (IOException ioe) { return cpath; } diff --git a/jdk/src/share/classes/sun/security/provider/PolicyFile.java b/jdk/src/share/classes/sun/security/provider/PolicyFile.java index 324e745f375..ed4757d3cff 100644 --- a/jdk/src/share/classes/sun/security/provider/PolicyFile.java +++ b/jdk/src/share/classes/sun/security/provider/PolicyFile.java @@ -1832,8 +1832,9 @@ public class PolicyFile extends java.security.Policy { return canonCs; } - // public for java.io.FilePermission - public static String canonPath(String path) throws IOException { + // Wrapper to return a canonical path that avoids calling getCanonicalPath() + // with paths that are intended to match all entries in the directory + private static String canonPath(String path) throws IOException { if (path.endsWith("*")) { path = path.substring(0, path.length()-1) + "-"; path = new File(path).getCanonicalPath(); From 793ab8527113c5fef0592fa998051c5e1e98103f Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Thu, 15 Oct 2009 18:27:39 -0700 Subject: [PATCH 072/172] 4428022: System.out.println(0.001) outputs 0.0010 Reviewed-by: darcy --- .../classes/sun/misc/FloatingDecimal.java | 6 +-- jdk/test/java/lang/Double/ToString.java | 39 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 jdk/test/java/lang/Double/ToString.java diff --git a/jdk/src/share/classes/sun/misc/FloatingDecimal.java b/jdk/src/share/classes/sun/misc/FloatingDecimal.java index f0316ff5631..279dd6180fe 100644 --- a/jdk/src/share/classes/sun/misc/FloatingDecimal.java +++ b/jdk/src/share/classes/sun/misc/FloatingDecimal.java @@ -730,7 +730,7 @@ public class FloatingDecimal{ * Thus we will need more than one digit if we're using * E-form */ - if ( decExp <= -3 || decExp >= 8 ){ + if ( decExp < -3 || decExp >= 8 ){ high = low = false; } while( ! low && ! high ){ @@ -783,7 +783,7 @@ public class FloatingDecimal{ * Thus we will need more than one digit if we're using * E-form */ - if ( decExp <= -3 || decExp >= 8 ){ + if ( decExp < -3 || decExp >= 8 ){ high = low = false; } while( ! low && ! high ){ @@ -847,7 +847,7 @@ public class FloatingDecimal{ * Thus we will need more than one digit if we're using * E-form */ - if ( decExp <= -3 || decExp >= 8 ){ + if ( decExp < -3 || decExp >= 8 ){ high = low = false; } while( ! low && ! high ){ diff --git a/jdk/test/java/lang/Double/ToString.java b/jdk/test/java/lang/Double/ToString.java new file mode 100644 index 00000000000..f553d4ebb6c --- /dev/null +++ b/jdk/test/java/lang/Double/ToString.java @@ -0,0 +1,39 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 4428022 + * @summary Tests for Double.toString + * @author Andrew Haley + */ + +public class ToString { + + public static void main(String args[]) { + if (!Double.toString(0.001).equals("0.001")) + throw new RuntimeException("Double.toString(0.001) is not \"0.001\""); + if (!Double.toString(0.002).equals("0.002")) + throw new RuntimeException("Double.toString(0.001) is not \"0.002\""); + } +} From 928ac69fcdea7506e2938db34c6cebe940e2b0f6 Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Fri, 16 Oct 2009 02:05:46 -0700 Subject: [PATCH 073/172] 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning 6889757: G1: enable card mark elision for initializing writes from compiled code (ReduceInitialCardMarks) Defer the (compiler-elided) card-mark upon a slow-path allocation until after the store and before the next subsequent safepoint; G1 now answers yes to can_elide_tlab_write_barriers(). Reviewed-by: jcoomes, kvn, never --- .../gc_implementation/g1/g1CollectedHeap.hpp | 36 ++++++- .../parallelScavenge/parallelScavengeHeap.cpp | 42 ++------- .../parallelScavenge/parallelScavengeHeap.hpp | 8 +- .../parallelScavengeHeap.inline.hpp | 8 ++ .../share/vm/gc_interface/collectedHeap.cpp | 93 +++++++++++++++++-- .../share/vm/gc_interface/collectedHeap.hpp | 22 ++++- .../src/share/vm/memory/genCollectedHeap.hpp | 11 +++ hotspot/src/share/vm/opto/graphKit.cpp | 9 ++ hotspot/src/share/vm/opto/library_call.cpp | 12 +-- hotspot/src/share/vm/opto/runtime.cpp | 20 ++-- hotspot/src/share/vm/opto/runtime.hpp | 4 +- hotspot/src/share/vm/runtime/thread.cpp | 5 + hotspot/src/share/vm/runtime/thread.hpp | 12 ++- 13 files changed, 209 insertions(+), 73 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 4ce7bdcfee8..5e07828267f 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -992,11 +992,39 @@ public: // Can a compiler initialize a new object without store barriers? // This permission only extends from the creation of a new object - // via a TLAB up to the first subsequent safepoint. + // via a TLAB up to the first subsequent safepoint. If such permission + // is granted for this heap type, the compiler promises to call + // defer_store_barrier() below on any slow path allocation of + // a new object for which such initializing store barriers will + // have been elided. G1, like CMS, allows this, but should be + // ready to provide a compensating write barrier as necessary + // if that storage came out of a non-young region. The efficiency + // of this implementation depends crucially on being able to + // answer very efficiently in constant time whether a piece of + // storage in the heap comes from a young region or not. + // See ReduceInitialCardMarks. virtual bool can_elide_tlab_store_barriers() const { - // Since G1's TLAB's may, on occasion, come from non-young regions - // as well. (Is there a flag controlling that? XXX) - return false; + return true; + } + + bool is_in_young(oop obj) { + HeapRegion* hr = heap_region_containing(obj); + return hr != NULL && hr->is_young(); + } + + // We don't need barriers for initializing stores to objects + // in the young gen: for the SATB pre-barrier, there is no + // pre-value that needs to be remembered; for the remembered-set + // update logging post-barrier, we don't maintain remembered set + // information for young gen objects. Note that non-generational + // G1 does not have any "young" objects, should not elide + // the rs logging barrier and so should always answer false below. + // However, non-generational G1 (-XX:-G1Gen) appears to have + // bit-rotted so was not tested below. + virtual bool can_elide_initializing_store_barrier(oop new_obj) { + assert(G1Gen || !is_in_young(new_obj), + "Non-generational G1 should never return true below"); + return is_in_young(new_obj); } // Can a compiler elide a store barrier when it writes diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp index 0835503d262..8396e7960b1 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp @@ -314,41 +314,6 @@ bool ParallelScavengeHeap::is_in_reserved(const void* p) const { return false; } -// Static method -bool ParallelScavengeHeap::is_in_young(oop* p) { - ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, - "Must be ParallelScavengeHeap"); - - PSYoungGen* young_gen = heap->young_gen(); - - if (young_gen->is_in_reserved(p)) { - return true; - } - - return false; -} - -// Static method -bool ParallelScavengeHeap::is_in_old_or_perm(oop* p) { - ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, - "Must be ParallelScavengeHeap"); - - PSOldGen* old_gen = heap->old_gen(); - PSPermGen* perm_gen = heap->perm_gen(); - - if (old_gen->is_in_reserved(p)) { - return true; - } - - if (perm_gen->is_in_reserved(p)) { - return true; - } - - return false; -} - // There are two levels of allocation policy here. // // When an allocation request fails, the requesting thread must invoke a VM @@ -764,6 +729,13 @@ void ParallelScavengeHeap::resize_all_tlabs() { CollectedHeap::resize_all_tlabs(); } +bool ParallelScavengeHeap::can_elide_initializing_store_barrier(oop new_obj) { + // We don't need barriers for stores to objects in the + // young gen and, a fortiori, for initializing stores to + // objects therein. + return is_in_young(new_obj); +} + // This method is used by System.gc() and JVMTI. void ParallelScavengeHeap::collect(GCCause::Cause cause) { assert(!Heap_lock->owned_by_self(), diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp index 5b19b7a5c0c..3bf7671b29a 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp @@ -129,8 +129,8 @@ class ParallelScavengeHeap : public CollectedHeap { return perm_gen()->is_in(p); } - static bool is_in_young(oop *p); // reserved part - static bool is_in_old_or_perm(oop *p); // reserved part + inline bool is_in_young(oop p); // reserved part + inline bool is_in_old_or_perm(oop p); // reserved part // Memory allocation. "gc_time_limit_was_exceeded" will // be set to true if the adaptive size policy determine that @@ -191,6 +191,10 @@ class ParallelScavengeHeap : public CollectedHeap { return true; } + // Return true if we don't we need a store barrier for + // initializing stores to an object at this address. + virtual bool can_elide_initializing_store_barrier(oop new_obj); + // Can a compiler elide a store barrier when it writes // a permanent oop into the heap? Applies when the compiler // is storing x to the heap, where x->is_perm() is true. diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp index bcc80ab630e..ccdbd043cb7 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp @@ -41,3 +41,11 @@ inline void ParallelScavengeHeap::invoke_full_gc(bool maximum_compaction) PSMarkSweep::invoke(maximum_compaction); } } + +inline bool ParallelScavengeHeap::is_in_young(oop p) { + return young_gen()->is_in_reserved(p); +} + +inline bool ParallelScavengeHeap::is_in_old_or_perm(oop p) { + return old_gen()->is_in_reserved(p) || perm_gen()->is_in_reserved(p); +} diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp index 7e2daebd4de..c775e6021b1 100644 --- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp @@ -137,6 +137,89 @@ HeapWord* CollectedHeap::allocate_from_tlab_slow(Thread* thread, size_t size) { return obj; } +void CollectedHeap::flush_deferred_store_barrier(JavaThread* thread) { + MemRegion deferred = thread->deferred_card_mark(); + if (!deferred.is_empty()) { + { + // Verify that the storage points to a parsable object in heap + DEBUG_ONLY(oop old_obj = oop(deferred.start());) + assert(is_in(old_obj), "Not in allocated heap"); + assert(!can_elide_initializing_store_barrier(old_obj), + "Else should have been filtered in defer_store_barrier()"); + assert(!is_in_permanent(old_obj), "Sanity: not expected"); + assert(old_obj->is_oop(true), "Not an oop"); + assert(old_obj->is_parsable(), "Will not be concurrently parsable"); + assert(deferred.word_size() == (size_t)(old_obj->size()), + "Mismatch: multiple objects?"); + } + BarrierSet* bs = barrier_set(); + assert(bs->has_write_region_opt(), "No write_region() on BarrierSet"); + bs->write_region(deferred); + // "Clear" the deferred_card_mark field + thread->set_deferred_card_mark(MemRegion()); + } + assert(thread->deferred_card_mark().is_empty(), "invariant"); +} + +// Helper for ReduceInitialCardMarks. For performance, +// compiled code may elide card-marks for initializing stores +// to a newly allocated object along the fast-path. We +// compensate for such elided card-marks as follows: +// (a) Generational, non-concurrent collectors, such as +// GenCollectedHeap(ParNew,DefNew,Tenured) and +// ParallelScavengeHeap(ParallelGC, ParallelOldGC) +// need the card-mark if and only if the region is +// in the old gen, and do not care if the card-mark +// succeeds or precedes the initializing stores themselves, +// so long as the card-mark is completed before the next +// scavenge. For all these cases, we can do a card mark +// at the point at which we do a slow path allocation +// in the old gen. For uniformity, however, we end +// up using the same scheme (see below) for all three +// cases (deferring the card-mark appropriately). +// (b) GenCollectedHeap(ConcurrentMarkSweepGeneration) requires +// in addition that the card-mark for an old gen allocated +// object strictly follow any associated initializing stores. +// In these cases, the memRegion remembered below is +// used to card-mark the entire region either just before the next +// slow-path allocation by this thread or just before the next scavenge or +// CMS-associated safepoint, whichever of these events happens first. +// (The implicit assumption is that the object has been fully +// initialized by this point, a fact that we assert when doing the +// card-mark.) +// (c) G1CollectedHeap(G1) uses two kinds of write barriers. When a +// G1 concurrent marking is in progress an SATB (pre-write-)barrier is +// is used to remember the pre-value of any store. Initializing +// stores will not need this barrier, so we need not worry about +// compensating for the missing pre-barrier here. Turning now +// to the post-barrier, we note that G1 needs a RS update barrier +// which simply enqueues a (sequence of) dirty cards which may +// optionally be refined by the concurrent update threads. Note +// that this barrier need only be applied to a non-young write, +// but, like in CMS, because of the presence of concurrent refinement +// (much like CMS' precleaning), must strictly follow the oop-store. +// Thus, using the same protocol for maintaining the intended +// invariants turns out, serendepitously, to be the same for all +// three collectors/heap types above. +// +// For each future collector, this should be reexamined with +// that specific collector in mind. +oop CollectedHeap::defer_store_barrier(JavaThread* thread, oop new_obj) { + // If a previous card-mark was deferred, flush it now. + flush_deferred_store_barrier(thread); + if (can_elide_initializing_store_barrier(new_obj)) { + // The deferred_card_mark region should be empty + // following the flush above. + assert(thread->deferred_card_mark().is_empty(), "Error"); + } else { + // Remember info for the newly deferred store barrier + MemRegion deferred = MemRegion((HeapWord*)new_obj, new_obj->size()); + assert(!deferred.is_empty(), "Error"); + thread->set_deferred_card_mark(deferred); + } + return new_obj; +} + size_t CollectedHeap::filler_array_hdr_size() { return size_t(arrayOopDesc::header_size(T_INT)); } @@ -225,16 +308,6 @@ void CollectedHeap::fill_with_objects(HeapWord* start, size_t words) fill_with_object_impl(start, words); } -oop CollectedHeap::new_store_barrier(oop new_obj) { - // %%% This needs refactoring. (It was imported from the server compiler.) - guarantee(can_elide_tlab_store_barriers(), "store barrier elision not supported"); - BarrierSet* bs = this->barrier_set(); - assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); - int new_size = new_obj->size(); - bs->write_region(MemRegion((HeapWord*)new_obj, new_size)); - return new_obj; -} - HeapWord* CollectedHeap::allocate_new_tlab(size_t size) { guarantee(false, "thread-local allocation buffers not supported"); return NULL; diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp index f39f1ebfa80..18148c8a30f 100644 --- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp @@ -415,9 +415,14 @@ class CollectedHeap : public CHeapObj { guarantee(false, "thread-local allocation buffers not supported"); return 0; } + // Can a compiler initialize a new object without store barriers? // This permission only extends from the creation of a new object - // via a TLAB up to the first subsequent safepoint. + // via a TLAB up to the first subsequent safepoint. If such permission + // is granted for this heap type, the compiler promises to call + // defer_store_barrier() below on any slow path allocation of + // a new object for which such initializing store barriers will + // have been elided. virtual bool can_elide_tlab_store_barriers() const = 0; // If a compiler is eliding store barriers for TLAB-allocated objects, @@ -425,8 +430,19 @@ class CollectedHeap : public CHeapObj { // an object allocated anywhere. The compiler's runtime support // promises to call this function on such a slow-path-allocated // object before performing initializations that have elided - // store barriers. Returns new_obj, or maybe a safer copy thereof. - virtual oop new_store_barrier(oop new_obj); + // store barriers. Returns new_obj, or maybe a safer copy thereof. + virtual oop defer_store_barrier(JavaThread* thread, oop new_obj); + + // Answers whether an initializing store to a new object currently + // allocated at the given address doesn't need a (deferred) store + // barrier. Returns "true" if it doesn't need an initializing + // store barrier; answers "false" if it does. + virtual bool can_elide_initializing_store_barrier(oop new_obj) = 0; + + // If the CollectedHeap was asked to defer a store barrier above, + // this informs it to flush such a deferred store barrier to the + // remembered set. + virtual void flush_deferred_store_barrier(JavaThread* thread); // Can a compiler elide a store barrier when it writes // a permanent oop into the heap? Applies when the compiler diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp index 1a04fb0a31a..8ac974e0a38 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp @@ -260,6 +260,17 @@ public: return true; } + // We don't need barriers for stores to objects in the + // young gen and, a fortiori, for initializing stores to + // objects therein. This applies to {DefNew,ParNew}+{Tenured,CMS} + // only and may need to be re-examined in case other + // kinds of collectors are implemented in the future. + virtual bool can_elide_initializing_store_barrier(oop new_obj) { + assert(UseParNewGC || UseSerialGC || UseConcMarkSweepGC, + "Check can_elide_initializing_store_barrier() for this collector"); + return is_in_youngest((void*)new_obj); + } + // Can a compiler elide a store barrier when it writes // a permanent oop into the heap? Applies when the compiler // is storing x to the heap, where x->is_perm() is true. diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index b178119f3e5..b63aae489ff 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -3186,6 +3186,15 @@ void GraphKit::write_barrier_post(Node* oop_store, return; } + if (use_ReduceInitialCardMarks() + && obj == just_allocated_object(control())) { + // We can skip marks on a freshly-allocated object in Eden. + // Keep this code in sync with maybe_defer_card_mark() in runtime.cpp. + // That routine informs GC to take appropriate compensating steps + // so as to make this card-mark elision safe. + return; + } + if (!use_precise) { // All card marks for a (non-array) instance are in one place: adr = obj; diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index dedf3492b64..1be04de6acf 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -4160,13 +4160,13 @@ bool LibraryCallKit::inline_native_clone(bool is_virtual) { result_mem ->set_req(_objArray_path, reset_memory()); } } - // We can dispense with card marks if we know the allocation - // comes out of eden (TLAB)... In fact, ReduceInitialCardMarks - // causes the non-eden paths to simulate a fresh allocation, - // insofar that no further card marks are required to initialize - // the object. - // Otherwise, there are no card marks to worry about. + // (We can dispense with card marks if we know the allocation + // comes out of eden (TLAB)... In fact, ReduceInitialCardMarks + // causes the non-eden paths to take compensating steps to + // simulate a fresh allocation, so that no further + // card marks are required in compiled code to initialize + // the object.) if (!stopped()) { copy_to_clone(obj, alloc_obj, obj_size, true, false); diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp index cbbbfacfcb5..2b3851961ee 100644 --- a/hotspot/src/share/vm/opto/runtime.cpp +++ b/hotspot/src/share/vm/opto/runtime.cpp @@ -143,18 +143,20 @@ const char* OptoRuntime::stub_name(address entry) { // We failed the fast-path allocation. Now we need to do a scavenge or GC // and try allocation again. -void OptoRuntime::do_eager_card_mark(JavaThread* thread) { +void OptoRuntime::maybe_defer_card_mark(JavaThread* thread) { // After any safepoint, just before going back to compiled code, - // we perform a card mark. This lets the compiled code omit - // card marks for initialization of new objects. - // Keep this code consistent with GraphKit::store_barrier. + // we inform the GC that we will be doing initializing writes to + // this object in the future without emitting card-marks, so + // GC may take any compensating steps. + // NOTE: Keep this code consistent with GraphKit::store_barrier. oop new_obj = thread->vm_result(); if (new_obj == NULL) return; assert(Universe::heap()->can_elide_tlab_store_barriers(), "compiler must check this first"); - new_obj = Universe::heap()->new_store_barrier(new_obj); + // GC may decide to give back a safer copy of new_obj. + new_obj = Universe::heap()->defer_store_barrier(thread, new_obj); thread->set_vm_result(new_obj); } @@ -197,8 +199,8 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(klassOopDesc* klass, JavaThrea JRT_BLOCK_END; if (GraphKit::use_ReduceInitialCardMarks()) { - // do them now so we don't have to do them on the fast path - do_eager_card_mark(thread); + // inform GC that we won't do card marks for initializing writes. + maybe_defer_card_mark(thread); } JRT_END @@ -236,8 +238,8 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(klassOopDesc* array_type, int len JRT_BLOCK_END; if (GraphKit::use_ReduceInitialCardMarks()) { - // do them now so we don't have to do them on the fast path - do_eager_card_mark(thread); + // inform GC that we won't do card marks for initializing writes. + maybe_defer_card_mark(thread); } JRT_END diff --git a/hotspot/src/share/vm/opto/runtime.hpp b/hotspot/src/share/vm/opto/runtime.hpp index 8a51b2facce..c3d8238ae1e 100644 --- a/hotspot/src/share/vm/opto/runtime.hpp +++ b/hotspot/src/share/vm/opto/runtime.hpp @@ -133,8 +133,8 @@ class OptoRuntime : public AllStatic { // Allocate storage for a objArray or typeArray static void new_array_C(klassOopDesc* array_klass, int len, JavaThread *thread); - // Post-allocation step for implementing ReduceInitialCardMarks: - static void do_eager_card_mark(JavaThread* thread); + // Post-slow-path-allocation step for implementing ReduceInitialCardMarks: + static void maybe_defer_card_mark(JavaThread* thread); // Allocate storage for a multi-dimensional arrays // Note: needs to be fixed for arbitrary number of dimensions diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index 05588d5fcae..38e3ac438b3 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -1213,6 +1213,7 @@ JavaThread::JavaThread(bool is_attaching) : { initialize(); _is_attaching = is_attaching; + assert(_deferred_card_mark.is_empty(), "Default MemRegion ctor"); } bool JavaThread::reguard_stack(address cur_sp) { @@ -2318,6 +2319,10 @@ void JavaThread::gc_prologue() { void JavaThread::oops_do(OopClosure* f, CodeBlobClosure* cf) { + // Flush deferred store-barriers, if any, associated with + // initializing stores done by this JavaThread in the current epoch. + Universe::heap()->flush_deferred_store_barrier(this); + // The ThreadProfiler oops_do is done from FlatProfiler::oops_do // since there may be more than one thread using each ThreadProfiler. diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp index 1def1aeec66..cb4d6168a82 100644 --- a/hotspot/src/share/vm/runtime/thread.hpp +++ b/hotspot/src/share/vm/runtime/thread.hpp @@ -684,8 +684,13 @@ class JavaThread: public Thread { methodOop _callee_target; // Oop results of VM runtime calls - oop _vm_result; // Used to pass back an oop result into Java code, GC-preserved - oop _vm_result_2; // Used to pass back an oop result into Java code, GC-preserved + oop _vm_result; // Used to pass back an oop result into Java code, GC-preserved + oop _vm_result_2; // Used to pass back an oop result into Java code, GC-preserved + + // See ReduceInitialCardMarks: this holds the precise space interval of + // the most recent slow path allocation for which compiled code has + // elided card-marks for performance along the fast-path. + MemRegion _deferred_card_mark; MonitorChunk* _monitor_chunks; // Contains the off stack monitors // allocated during deoptimization @@ -1082,6 +1087,9 @@ class JavaThread: public Thread { oop vm_result_2() const { return _vm_result_2; } void set_vm_result_2 (oop x) { _vm_result_2 = x; } + MemRegion deferred_card_mark() const { return _deferred_card_mark; } + void set_deferred_card_mark(MemRegion mr) { _deferred_card_mark = mr; } + // Exception handling for compiled methods oop exception_oop() const { return _exception_oop; } int exception_stack_size() const { return _exception_stack_size; } From ac9bcbd819ccf620c73ff9964f39323ad9b8d2f6 Mon Sep 17 00:00:00 2001 From: Jennifer Godinez Date: Fri, 16 Oct 2009 09:32:29 -0700 Subject: [PATCH 074/172] 6680634: Printing: "Collate" is ignored under Windows Vista x64 Reviewed-by: campbell, prr --- jdk/src/windows/native/sun/windows/awt_PrintControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp b/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp index cc562ec0056..b68bb5f3bdd 100644 --- a/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp +++ b/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp @@ -687,7 +687,7 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env, // Now, set-up the struct for the real calls to ::PrintDlg and ::CreateDC pd.hwndOwner = hwndOwner; - pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC; + pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE; pd.lpfnPrintHook = (LPPRINTHOOKPROC)PrintDlgHook; if (env->CallBooleanMethod(printCtrl, AwtPrintControl::getCollateID)) { From e634c0ee8e6d491796cb9baefe720d729745edd3 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 16 Oct 2009 12:56:50 -0700 Subject: [PATCH 075/172] 6888367: classfile library parses signature attributes incorrectly Reviewed-by: ksrini --- .../com/sun/tools/classfile/Signature.java | 103 ++-- .../classes/com/sun/tools/classfile/Type.java | 184 +++++-- .../com/sun/tools/javap/ClassWriter.java | 6 +- .../javap/LocalVariableTypeTableWriter.java | 2 +- .../javap/classfile/6888367/T6888367.java | 511 ++++++++++++++++++ 5 files changed, 701 insertions(+), 105 deletions(-) create mode 100644 langtools/test/tools/javap/classfile/6888367/T6888367.java diff --git a/langtools/src/share/classes/com/sun/tools/classfile/Signature.java b/langtools/src/share/classes/com/sun/tools/classfile/Signature.java index 06b2338d561..0451fdd1770 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/Signature.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/Signature.java @@ -27,6 +27,7 @@ package com.sun.tools.classfile; import java.util.ArrayList; import java.util.List; +import com.sun.tools.classfile.Type.*; /** * See JVMS3 4.4.4. @@ -50,19 +51,19 @@ public class Signature extends Descriptor { @Override public int getParameterCount(ConstantPool constant_pool) throws ConstantPoolException { - Type.MethodType m = (Type.MethodType) getType(constant_pool); - return m.argTypes.size(); + MethodType m = (MethodType) getType(constant_pool); + return m.paramTypes.size(); } @Override public String getParameterTypes(ConstantPool constant_pool) throws ConstantPoolException { - Type.MethodType m = (Type.MethodType) getType(constant_pool); + MethodType m = (MethodType) getType(constant_pool); StringBuilder sb = new StringBuilder(); sb.append("("); String sep = ""; - for (Type argType: m.argTypes) { + for (Type paramType: m.paramTypes) { sb.append(sep); - sb.append(argType); + sb.append(paramType); sep = ", "; } sb.append(")"); @@ -71,7 +72,7 @@ public class Signature extends Descriptor { @Override public String getReturnType(ConstantPool constant_pool) throws ConstantPoolException { - Type.MethodType m = (Type.MethodType) getType(constant_pool); + MethodType m = (MethodType) getType(constant_pool); return m.returnType.toString(); } @@ -84,12 +85,12 @@ public class Signature extends Descriptor { this.sig = sig; sigp = 0; - List typeArgTypes = null; + List typeParamTypes = null; if (sig.charAt(sigp) == '<') - typeArgTypes = parseTypeArgTypes(); + typeParamTypes = parseTypeParamTypes(); if (sig.charAt(sigp) == '(') { - List argTypes = parseTypeSignatures(')'); + List paramTypes = parseTypeSignatures(')'); Type returnType = parseTypeSignature(); List throwsTypes = null; while (sigp < sig.length() && sig.charAt(sigp) == '^') { @@ -98,16 +99,19 @@ public class Signature extends Descriptor { throwsTypes = new ArrayList(); throwsTypes.add(parseTypeSignature()); } - return new Type.MethodType(typeArgTypes, argTypes, returnType, throwsTypes); + return new MethodType(typeParamTypes, paramTypes, returnType, throwsTypes); } else { Type t = parseTypeSignature(); - if (typeArgTypes == null && sigp == sig.length()) + if (typeParamTypes == null && sigp == sig.length()) return t; Type superclass = t; - List superinterfaces = new ArrayList(); - while (sigp < sig.length()) + List superinterfaces = null; + while (sigp < sig.length()) { + if (superinterfaces == null) + superinterfaces = new ArrayList(); superinterfaces.add(parseTypeSignature()); - return new Type.ClassSigType(typeArgTypes, superclass, superinterfaces); + } + return new ClassSigType(typeParamTypes, superclass, superinterfaces); } } @@ -116,61 +120,61 @@ public class Signature extends Descriptor { switch (sig.charAt(sigp)) { case 'B': sigp++; - return new Type.SimpleType("byte"); + return new SimpleType("byte"); case 'C': sigp++; - return new Type.SimpleType("char"); + return new SimpleType("char"); case 'D': sigp++; - return new Type.SimpleType("double"); + return new SimpleType("double"); case 'F': sigp++; - return new Type.SimpleType("float"); + return new SimpleType("float"); case 'I': sigp++; - return new Type.SimpleType("int"); + return new SimpleType("int"); case 'J': sigp++; - return new Type.SimpleType("long"); + return new SimpleType("long"); case 'L': return parseClassTypeSignature(); case 'S': sigp++; - return new Type.SimpleType("short"); + return new SimpleType("short"); case 'T': return parseTypeVariableSignature(); case 'V': sigp++; - return new Type.SimpleType("void"); + return new SimpleType("void"); case 'Z': sigp++; - return new Type.SimpleType("boolean"); + return new SimpleType("boolean"); case '[': sigp++; - return new Type.ArrayType(parseTypeSignature()); + return new ArrayType(parseTypeSignature()); case '*': sigp++; - return new Type.WildcardType(); + return new WildcardType(); case '+': sigp++; - return new Type.WildcardType("extends", parseTypeSignature()); + return new WildcardType(WildcardType.Kind.EXTENDS, parseTypeSignature()); case '-': sigp++; - return new Type.WildcardType("super", parseTypeSignature()); + return new WildcardType(WildcardType.Kind.SUPER, parseTypeSignature()); default: throw new IllegalStateException(debugInfo()); @@ -194,30 +198,22 @@ public class Signature extends Descriptor { private Type parseClassTypeSignatureRest() { StringBuilder sb = new StringBuilder(); - Type t = null; - char sigch; - while (true) { + List argTypes = null; + ClassType t = null; + char sigch ; + + do { switch (sigch = sig.charAt(sigp)) { - case '/': - sigp++; - sb.append("."); + case '<': + argTypes = parseTypeSignatures('>'); break; case '.': - sigp++; - if (t == null) - t = new Type.SimpleType(sb.toString()); - return new Type.InnerClassType(t, parseClassTypeSignatureRest()); - case ';': sigp++; - if (t == null) - t = new Type.SimpleType(sb.toString()); - return t; - - case '<': - List argTypes = parseTypeSignatures('>'); - t = new Type.ClassType(sb.toString(), argTypes); + t = new ClassType(t, sb.toString(), argTypes); + sb.setLength(0); + argTypes = null; break; default: @@ -225,21 +221,22 @@ public class Signature extends Descriptor { sb.append(sigch); break; } - } + } while (sigch != ';'); + + return t; } - private List parseTypeArgTypes() { + private List parseTypeParamTypes() { assert sig.charAt(sigp) == '<'; sigp++; - List types = null; - types = new ArrayList(); + List types = new ArrayList(); while (sig.charAt(sigp) != '>') - types.add(parseTypeArgType()); + types.add(parseTypeParamType()); sigp++; return types; } - private Type parseTypeArgType() { + private TypeParamType parseTypeParamType() { int sep = sig.indexOf(":", sigp); String name = sig.substring(sigp, sep); Type classBound = null; @@ -253,13 +250,13 @@ public class Signature extends Descriptor { interfaceBounds = new ArrayList(); interfaceBounds.add(parseTypeSignature()); } - return new Type.TypeArgType(name, classBound, interfaceBounds); + return new TypeParamType(name, classBound, interfaceBounds); } private Type parseTypeVariableSignature() { sigp++; int sep = sig.indexOf(';', sigp); - Type t = new Type.SimpleType(sig.substring(sigp, sep)); + Type t = new SimpleType(sig.substring(sigp, sep)); sigp = sep + 1; return t; } diff --git a/langtools/src/share/classes/com/sun/tools/classfile/Type.java b/langtools/src/share/classes/com/sun/tools/classfile/Type.java index 869c4ca855b..ff461c89fde 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/Type.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/Type.java @@ -31,6 +31,9 @@ import java.util.List; import java.util.Set; /* + * Family of classes used to represent the parsed form of a {@link Descriptor} + * or {@link Signature}. + * *

This is NOT part of any API supported by Sun Microsystems. If * you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or @@ -62,11 +65,26 @@ public abstract class Type { R visitMethodType(MethodType type, P p); R visitClassSigType(ClassSigType type, P p); R visitClassType(ClassType type, P p); - R visitInnerClassType(InnerClassType type, P p); - R visitTypeArgType(TypeArgType type, P p); + R visitTypeParamType(TypeParamType type, P p); R visitWildcardType(WildcardType type, P p); } + /** + * Represents a type signature with a simple name. The name may be that of a + * primitive type, such "{@code int}, {@code float}, etc + * or that of a type argument, such as {@code T}, {@code K}, {@code V}, etc. + * + * See: + * JVMS 4.3.2 + * BaseType: + * {@code B}, {@code C}, {@code D}, {@code F}, {@code I}, + * {@code J}, {@code S}, {@code Z}; + * VoidDescriptor: + * {@code V}; + * JVMS 4.3.4 + * TypeVariableSignature: + * {@code T} Identifier {@code ;} + */ public static class SimpleType extends Type { public SimpleType(String name) { this.name = name; @@ -91,6 +109,14 @@ public abstract class Type { public final String name; } + /** + * Represents an array type signature. + * + * See: + * JVMS 4.3.4 + * ArrayTypeSignature: + * {@code [} TypeSignature {@code ]} + */ public static class ArrayType extends Type { public ArrayType(Type elemType) { this.elemType = elemType; @@ -108,17 +134,26 @@ public abstract class Type { public final Type elemType; } + /** + * Represents a method type signature. + * + * See; + * JVMS 4.3.4 + * MethodTypeSignature: + * FormalTypeParameters_opt {@code (} TypeSignature* {@code)} ReturnType + * ThrowsSignature* + */ public static class MethodType extends Type { - public MethodType(List argTypes, Type resultType) { - this(null, argTypes, resultType, null); + public MethodType(List paramTypes, Type resultType) { + this(null, paramTypes, resultType, null); } - public MethodType(List typeArgTypes, - List argTypes, + public MethodType(List typeParamTypes, + List paramTypes, Type returnType, List throwsTypes) { - this.typeArgTypes = typeArgTypes; - this.argTypes = argTypes; + this.typeParamTypes = typeParamTypes; + this.paramTypes = paramTypes; this.returnType = returnType; this.throwsTypes = throwsTypes; } @@ -130,22 +165,32 @@ public abstract class Type { @Override public String toString() { StringBuilder sb = new StringBuilder(); - appendIfNotEmpty(sb, "<", typeArgTypes, "> "); + appendIfNotEmpty(sb, "<", typeParamTypes, "> "); sb.append(returnType); - append(sb, " (", argTypes, ")"); + append(sb, " (", paramTypes, ")"); appendIfNotEmpty(sb, " throws ", throwsTypes, ""); return sb.toString(); } - public final List typeArgTypes; - public final List argTypes; + public final List typeParamTypes; + public final List paramTypes; public final Type returnType; public final List throwsTypes; } + /** + * Represents a class signature. These describe the signature of + * a class that has type arguments. + * + * See: + * JVMS 4.3.4 + * ClassSignature: + * FormalTypeParameters_opt SuperclassSignature SuperinterfaceSignature* + */ public static class ClassSigType extends Type { - public ClassSigType(List typeArgTypes, Type superclassType, List superinterfaceTypes) { - this.typeArgTypes = typeArgTypes; + public ClassSigType(List typeParamTypes, Type superclassType, + List superinterfaceTypes) { + this.typeParamTypes = typeParamTypes; this.superclassType = superclassType; this.superinterfaceTypes = superinterfaceTypes; } @@ -157,7 +202,7 @@ public abstract class Type { @Override public String toString() { StringBuilder sb = new StringBuilder(); - appendIfNotEmpty(sb, "<", typeArgTypes, ">"); + appendIfNotEmpty(sb, "<", typeParamTypes, ">"); if (superclassType != null) { sb.append(" extends "); sb.append(superclassType); @@ -166,13 +211,30 @@ public abstract class Type { return sb.toString(); } - public final List typeArgTypes; + public final List typeParamTypes; public final Type superclassType; public final List superinterfaceTypes; } + /** + * Represents a class type signature. This is used to represent a + * reference to a class, such as in a field, parameter, return type, etc. + * + * See: + * JVMS 4.3.4 + * ClassTypeSignature: + * {@code L} PackageSpecifier_opt SimpleClassTypeSignature + * ClassTypeSignatureSuffix* {@code ;} + * PackageSpecifier: + * Identifier {@code /} PackageSpecifier* + * SimpleClassTypeSignature: + * Identifier TypeArguments_opt } + * ClassTypeSignatureSuffix: + * {@code .} SimpleClassTypeSignature + */ public static class ClassType extends Type { - public ClassType(String name, List typeArgs) { + public ClassType(ClassType outerType, String name, List typeArgs) { + this.outerType = outerType; this.name = name; this.typeArgs = typeArgs; } @@ -181,47 +243,54 @@ public abstract class Type { return visitor.visitClassType(this, data); } + public String getBinaryName() { + if (outerType == null) + return name; + else + return (outerType.getBinaryName() + "$" + name); + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); + if (outerType != null) { + sb.append(outerType); + sb.append("."); + } sb.append(name); appendIfNotEmpty(sb, "<", typeArgs, ">"); return sb.toString(); } + public final ClassType outerType; public final String name; public final List typeArgs; } - - public static class InnerClassType extends Type { - public InnerClassType(Type outerType, Type innerType) { - this.outerType = outerType; - this.innerType = innerType; - } - - public R accept(Visitor visitor, D data) { - return visitor.visitInnerClassType(this, data); - } - - @Override - public String toString() { - return outerType + "." + innerType; - } - - public final Type outerType; - public final Type innerType; - } - - public static class TypeArgType extends Type { - public TypeArgType(String name, Type classBound, List interfaceBounds) { + /** + * Represents a FormalTypeParameter. These are used to declare the type + * parameters for generic classes and methods. + * + * See: + * JVMS 4.3.4 + * FormalTypeParameters: + * {@code <} FormalTypeParameter+ {@code >} + * FormalTypeParameter: + * Identifier ClassBound InterfaceBound* + * ClassBound: + * {@code :} FieldTypeSignature_opt + * InterfaceBound: + * {@code :} FieldTypeSignature + */ + public static class TypeParamType extends Type { + public TypeParamType(String name, Type classBound, List interfaceBounds) { this.name = name; this.classBound = classBound; this.interfaceBounds = interfaceBounds; } public R accept(Visitor visitor, D data) { - return visitor.visitTypeArgType(this, data); + return visitor.visitTypeParamType(this, data); } @Override @@ -249,12 +318,25 @@ public abstract class Type { public final List interfaceBounds; } + /** + * Represents a wildcard type argument. A type argument that is not a + * wildcard type argument will be represented by a ClassType, ArrayType, etc. + * + * See: + * JVMS 4.3.4 + * TypeArgument: + * WildcardIndicator_opt FieldTypeSignature + * {@code *} + * WildcardIndicator: + * {@code +} + * {@code -} + */ public static class WildcardType extends Type { + public enum Kind { UNBOUNDED, EXTENDS, SUPER }; public WildcardType() { - this(null, null); + this(Kind.UNBOUNDED, null); } - - public WildcardType(String kind, Type boundType) { + public WildcardType(Kind kind, Type boundType) { this.kind = kind; this.boundType = boundType; } @@ -265,13 +347,19 @@ public abstract class Type { @Override public String toString() { - if (kind == null) - return "?"; - else - return "? " + kind + " " + boundType; + switch (kind) { + case UNBOUNDED: + return "?"; + case EXTENDS: + return "? extends " + boundType; + case SUPER: + return "? super " + boundType; + default: + throw new AssertionError(); + } } - public final String kind; + public final Kind kind; public final Type boundType; } } diff --git a/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java index 9d657ee4d55..3016583a482 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java @@ -179,10 +179,10 @@ public class ClassWriter extends BasicWriter { // The signature parser cannot disambiguate between a // FieldType and a ClassSignatureType that only contains a superclass type. if (t instanceof Type.ClassSigType) - print(t); + print(getJavaName(t.toString())); else { print(" extends "); - print(t); + print(getJavaName(t.toString())); } } catch (ConstantPoolException e) { print(report(e)); @@ -310,7 +310,7 @@ public class ClassWriter extends BasicWriter { writeModifiers(flags.getMethodModifiers()); if (methodType != null) { - writeListIfNotEmpty("<", methodType.typeArgTypes, "> "); + writeListIfNotEmpty("<", methodType.typeParamTypes, "> "); } if (getName(m).equals("")) { print(getJavaName(classFile)); diff --git a/langtools/src/share/classes/com/sun/tools/javap/LocalVariableTypeTableWriter.java b/langtools/src/share/classes/com/sun/tools/javap/LocalVariableTypeTableWriter.java index adec4a8dd84..842f1f5a3d1 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/LocalVariableTypeTableWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/LocalVariableTypeTableWriter.java @@ -125,7 +125,7 @@ public class LocalVariableTypeTableWriter extends InstructionDetailWriter { print(" // "); Descriptor d = new Signature(entry.signature_index); try { - print(d.getFieldType(constant_pool)); + print(d.getFieldType(constant_pool).toString().replace("/", ".")); } catch (InvalidDescriptor e) { print(report(e)); } catch (ConstantPoolException e) { diff --git a/langtools/test/tools/javap/classfile/6888367/T6888367.java b/langtools/test/tools/javap/classfile/6888367/T6888367.java new file mode 100644 index 00000000000..44f822f8803 --- /dev/null +++ b/langtools/test/tools/javap/classfile/6888367/T6888367.java @@ -0,0 +1,511 @@ +/* + * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.io.*; +import java.net.*; +import java.util.*; +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.Type.ArrayType; +import com.sun.tools.classfile.Type.ClassSigType; +import com.sun.tools.classfile.Type.ClassType; +import com.sun.tools.classfile.Type.MethodType; +import com.sun.tools.classfile.Type.SimpleType; +import com.sun.tools.classfile.Type.TypeParamType; +import com.sun.tools.classfile.Type.WildcardType; + +/* + * @test + * @bug 6888367 + * @summary classfile library parses signature attributes incorrectly + */ + +/* + * This test is a pretty detailed test both of javac signature generation and classfile + * signature parsing. The first part of the test tests all the examples given in the + * second part of the test. Each example comes with one or two annotations, @Desc, @Sig, + * for the descriptor and signature of the annotated declaration. Annotations are + * provided whenever the annotated item is expected to have a corresponding value. + * Each annotation has two argument values. The first arg is the expected value of the + * descriptor/signature as found in the class file. This value is mostly for documentation + * purposes in reading the test. The second value is the rendering of the descriptor or + * signature using a custom Type visitor that explicitly includes an indication of the + * Type classes being used to represent the descriptor/signature. Thus we test + * that the descriptor/signature is being parsed into the expected type tree structure. + */ +public class T6888367 { + + public static void main(String... args) throws Exception { + new T6888367().run(); + } + + public void run() throws Exception { + ClassFile cf = getClassFile("Test"); + + testFields(cf); + testMethods(cf); + testInnerClasses(cf); // recursive + + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + void testFields(ClassFile cf) throws Exception { + String cn = cf.getName(); + ConstantPool cp = cf.constant_pool; + for (Field f: cf.fields) { + test("field " + cn + "." + f.getName(cp), f.descriptor, f.attributes, cp); + } + } + + void testMethods(ClassFile cf) throws Exception { + String cn = cf.getName(); + ConstantPool cp = cf.constant_pool; + for (Method m: cf.methods) { + test("method " + cn + "." + m.getName(cp), m.descriptor, m.attributes, cp); + } + } + + void testInnerClasses(ClassFile cf) throws Exception { + ConstantPool cp = cf.constant_pool; + InnerClasses_attribute ic = + (InnerClasses_attribute) cf.attributes.get(Attribute.InnerClasses); + for (InnerClasses_attribute.Info info: ic.classes) { + String outerClassName = cp.getClassInfo(info.outer_class_info_index).getName(); + if (!outerClassName.equals(cf.getName())) { + continue; + } + String innerClassName = cp.getClassInfo(info.inner_class_info_index).getName(); + ClassFile icf = getClassFile(innerClassName); + test("class " + innerClassName, null, icf.attributes, icf.constant_pool); + testInnerClasses(icf); + } + } + + void test(String name, Descriptor desc, Attributes attrs, ConstantPool cp) + throws Exception { + AnnotValues d = getDescValue(attrs, cp); + AnnotValues s = getSigValue(attrs, cp); + if (d == null && s == null) // not a test field or method if no @Desc or @Sig given + return; + + System.err.println(name); + + if (desc != null) { + System.err.println(" descriptor: " + desc.getValue(cp)); + checkEqual(d.raw, desc.getValue(cp)); + Type dt = new Signature(desc.index).getType(cp); + checkEqual(d.type, tp.print(dt)); + } + + Signature_attribute sa = (Signature_attribute) attrs.get(Attribute.Signature); + if (sa != null) + System.err.println(" signature: " + sa.getSignature(cp)); + + if (s != null || sa != null) { + if (s != null && sa != null) { + checkEqual(s.raw, sa.getSignature(cp)); + Type st = new Signature(sa.signature_index).getType(cp); + checkEqual(s.type, tp.print(st)); + } else if (s != null) + error("@Sig annotation found but not Signature attribute"); + else + error("Signature attribute found but no @Sig annotation"); + } + + System.err.println(); + } + + + ClassFile getClassFile(String name) throws IOException, ConstantPoolException { + URL url = getClass().getResource(name + ".class"); + InputStream in = url.openStream(); + try { + return ClassFile.read(in); + } finally { + in.close(); + } + } + + AnnotValues getDescValue(Attributes attrs, ConstantPool cp) throws Exception { + return getAnnotValues(Desc.class.getName(), attrs, cp); + } + + AnnotValues getSigValue(Attributes attrs, ConstantPool cp) throws Exception { + return getAnnotValues(Sig.class.getName(), attrs, cp); + } + + static class AnnotValues { + AnnotValues(String raw, String type) { + this.raw = raw; + this.type = type; + } + final String raw; + final String type; + } + + AnnotValues getAnnotValues(String annotName, Attributes attrs, ConstantPool cp) + throws Exception { + RuntimeInvisibleAnnotations_attribute annots = + (RuntimeInvisibleAnnotations_attribute)attrs.get(Attribute.RuntimeInvisibleAnnotations); + if (annots != null) { + for (Annotation a: annots.annotations) { + if (cp.getUTF8Value(a.type_index).equals("L" + annotName + ";")) { + Annotation.Primitive_element_value pv0 = + (Annotation.Primitive_element_value) a.element_value_pairs[0].value; + Annotation.Primitive_element_value pv1 = + (Annotation.Primitive_element_value) a.element_value_pairs[1].value; + return new AnnotValues( + cp.getUTF8Value(pv0.const_value_index), + cp.getUTF8Value(pv1.const_value_index)); + } + } + } + return null; + + } + + void checkEqual(String expect, String found) { + if (!(expect == null ? found == null : expect.equals(found))) { + System.err.println("expected: " + expect); + System.err.println(" found: " + found); + error("unexpected values found"); + } + } + + void error(String msg) { + System.err.println("error: " + msg); + errors++; + } + + int errors; + + TypePrinter tp = new TypePrinter(); + + class TypePrinter implements Type.Visitor { + String print(Type t) { + return t == null ? null : t.accept(this, null); + } + String print(String pre, List ts, String post) { + if (ts == null) + return null; + StringBuilder sb = new StringBuilder(); + sb.append(pre); + String sep = ""; + for (Type t: ts) { + sb.append(sep); + sb.append(print(t)); + sep = ","; + } + sb.append(post); + return sb.toString(); + } + + public String visitSimpleType(SimpleType type, Void p) { + return "S{" + type.name + "}"; + } + + public String visitArrayType(ArrayType type, Void p) { + return "A{" + print(type.elemType) + "}"; + } + + public String visitMethodType(MethodType type, Void p) { + StringBuilder sb = new StringBuilder(); + sb.append("M{"); + if (type.typeParamTypes != null) + sb.append(print("<", type.typeParamTypes, ">")); + sb.append(print(type.returnType)); + sb.append(print("(", type.paramTypes, ")")); + if (type.throwsTypes != null) + sb.append(print("", type.throwsTypes, "")); + sb.append("}"); + return sb.toString(); + } + + public String visitClassSigType(ClassSigType type, Void p) { + StringBuilder sb = new StringBuilder(); + sb.append("CS{"); + if (type.typeParamTypes != null) + sb.append(print("<", type.typeParamTypes, ">")); + sb.append(print(type.superclassType)); + if (type.superinterfaceTypes != null) + sb.append(print("i(", type.superinterfaceTypes, ")")); + sb.append("}"); + return sb.toString(); + } + + public String visitClassType(ClassType type, Void p) { + StringBuilder sb = new StringBuilder(); + sb.append("C{"); + if (type.outerType != null) { + sb.append(print(type.outerType)); + sb.append("."); + } + sb.append(type.name); + if (type.typeArgs != null) + sb.append(print("<", type.typeArgs, ">")); + sb.append("}"); + return sb.toString(); + } + + public String visitTypeParamType(TypeParamType type, Void p) { + StringBuilder sb = new StringBuilder(); + sb.append("TA{"); + sb.append(type.name); + if (type.classBound != null) { + sb.append(":c"); + sb.append(print(type.classBound)); + } + if (type.interfaceBounds != null) + sb.append(print(":i", type.interfaceBounds, "")); + sb.append("}"); + return sb.toString(); + } + + public String visitWildcardType(WildcardType type, Void p) { + switch (type.kind) { + case UNBOUNDED: + return "W{?}"; + case EXTENDS: + return "W{e," + print(type.boundType) + "}"; + case SUPER: + return "W{s," + print(type.boundType) + "}"; + default: + throw new AssertionError(); + } + } + + }; +} + + +@interface Desc { + String d(); + String t(); +} + +@interface Sig { + String s(); + String t(); +} + +class Clss { } +interface Intf { } +class GenClss { } + +class Test { + // fields + + @Desc(d="Z", t="S{boolean}") + boolean z; + + @Desc(d="B", t="S{byte}") + byte b; + + @Desc(d="C", t="S{char}") + char c; + + @Desc(d="D", t="S{double}") + double d; + + @Desc(d="F", t="S{float}") + float f; + + @Desc(d="I", t="S{int}") + int i; + + @Desc(d="J", t="S{long}") + long l; + + @Desc(d="S", t="S{short}") + short s; + + @Desc(d="LClss;", t="C{Clss}") + Clss clss; + + @Desc(d="LIntf;", t="C{Intf}") + Intf intf; + + @Desc(d="[I", t="A{S{int}}") + int[] ai; + + @Desc(d="[LClss;", t="A{C{Clss}}") + Clss[] aClss; + + @Desc(d="LGenClss;", t="C{GenClss}") + @Sig(s="LGenClss;", t="C{GenClss}") + GenClss genClass; + + // methods, return types + + @Desc(d="()V", t="M{S{void}()}") + void mv0() { } + + @Desc(d="()I", t="M{S{int}()}") + int mi0() { return 0; } + + @Desc(d="()LClss;", t="M{C{Clss}()}") + Clss mclss0() { return null; } + + @Desc(d="()[I", t="M{A{S{int}}()}") + int[] mai0() { return null; } + + @Desc(d="()[LClss;", t="M{A{C{Clss}}()}") + Clss[] maClss0() { return null; } + + @Desc(d="()LGenClss;", t="M{C{GenClss}()}") + @Sig(s="()LGenClss;", t="M{C{GenClss}()}") + GenClss mgenClss0() { return null; } + + @Desc(d="()LGenClss;", t="M{C{GenClss}()}") + @Sig(s="()LGenClss<*>;", t="M{C{GenClss}()}") + GenClss mgenClssW0() { return null; } + + @Desc(d="()LGenClss;", t="M{C{GenClss}()}") + @Sig(s="()LGenClss<+LClss;>;", t="M{C{GenClss}()}") + GenClss mgenClssWExtClss0() { return null; } + + @Desc(d="()LGenClss;", t="M{C{GenClss}()}") + @Sig(s="()LGenClss<-LClss;>;", t="M{C{GenClss}()}") + GenClss mgenClssWSupClss0() { return null; } + + @Desc(d="()Ljava/lang/Object;", t="M{C{java/lang/Object}()}") + @Sig(s="()TT;", t="M{S{T}()}") + T mt0() { return null; } + + @Desc(d="()LGenClss;", t="M{C{GenClss}()}") + @Sig(s="()LGenClss<+TT;>;", + t="M{C{GenClss}()}") + GenClss mgenClssWExtT0() { return null; } + + @Desc(d="()LGenClss;", t="M{C{GenClss}()}") + @Sig(s="()LGenClss<-TT;>;", t="M{C{GenClss}()}") + GenClss mgenClssWSupT0() { return null; } + + // methods, arg types + + @Desc(d="(I)V", t="M{S{void}(S{int})}") + void mi1(int arg) { } + + @Desc(d="(LClss;)V", t="M{S{void}(C{Clss})}") + void mclss1(Clss arg) { } + + @Desc(d="([I)V", t="M{S{void}(A{S{int}})}") + void mai1(int[] arg) { } + + @Desc(d="([LClss;)V", t="M{S{void}(A{C{Clss}})}") + void maClss1(Clss[] arg) { } + + @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}") + @Sig(s="(LGenClss;)V", t="M{S{void}(C{GenClss})}") + void mgenClss1(GenClss arg) { } + + @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}") + @Sig(s="(LGenClss<*>;)V", t="M{S{void}(C{GenClss})}") + void mgenClssW1(GenClss arg) { } + + @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}") + @Sig(s="(LGenClss<+LClss;>;)V", t="M{S{void}(C{GenClss})}") + void mgenClssWExtClss1(GenClss arg) { } + + @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}") + @Sig(s="(LGenClss<-LClss;>;)V", t="M{S{void}(C{GenClss})}") + void mgenClssWSupClss1(GenClss arg) { } + + @Desc(d="(Ljava/lang/Object;)V", t="M{S{void}(C{java/lang/Object})}") + @Sig(s="(TT;)V", + t="M{S{void}(S{T})}") + void mt1(T arg) { } + + @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}") + @Sig(s="(LGenClss<+TT;>;)V", + t="M{S{void}(C{GenClss})}") + void mgenClssWExtT1(GenClss arg) { } + + @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}") + @Sig(s="(LGenClss<-TT;>;)V", + t="M{S{void}(C{GenClss})}") + void mgenClssWSupT1(GenClss arg) { } + + // methods, throws + + @Desc(d="()V", t="M{S{void}()}") + void m_E() throws Exception { } + + @Desc(d="()V", t="M{S{void}()}") + @Sig(s="()V^TT;", + t="M{S{void}()S{T}}") + void m_T() throws T { } + + // inner classes + + static class X { + // no sig + class P { } + + @Sig(s="LTest$X$P;", + t="CS{C{Test$X$P}}") + class Q extends P { } + + @Sig(s="LTest$X$Q;", + t="CS{C{Test$X$Q}}") + class R extends Q { } + } + + @Sig(s="Ljava/lang/Object;", + t="CS{C{java/lang/Object}}") + static class Y { + // no sig + class P { } + + @Sig(s="LTest$Y.P;", + t="CS{C{C{Test$Y}.P}}") + class Q extends P { } + + @Sig(s="LTest$Y.Q;", + t="CS{C{C{Test$Y}.Q}}") + class R extends Q { + // no sig + class R1 { } + + @Sig(s="LTest$Y.R.R1;", + t="CS{C{C{C{Test$Y}.R}.R1}}") + class R2 extends R1 { } + } + + @Sig(s="LTest$Y.Q;", t="C{C{Test$Y}.Q}") + class S extends Q { + // no sig + class S1 { } + + @Sig(s="LTest$Y.S.S1;", + t="CS{C{C{C{Test$Y}.S}.S1}}") + class S2 extends S1 { } + + @Sig(s="LTest$Y.S.S2;", + t="C{C{C{Test$Y}.S}.S2}") + class S3 extends S2 { } + } + } +} + + From 2134a92922d318366d48f04936dbad3b1f71b65a Mon Sep 17 00:00:00 2001 From: John R Rose Date: Sat, 17 Oct 2009 19:51:05 -0700 Subject: [PATCH 076/172] 6815692: method handle code needs some cleanup (post-6655638) Correctly raise exceptions, support safe bitwise "raw" conversions, fix bugs revealed by VerifyMethodHandles, remove dead code, improve debugging support Reviewed-by: never, twisti --- hotspot/src/cpu/x86/vm/methodHandles_x86.cpp | 122 ++++++++---- .../cpu/x86/vm/templateInterpreter_x86_32.cpp | 3 +- .../src/share/vm/classfile/javaClasses.hpp | 27 +-- .../share/vm/classfile/systemDictionary.cpp | 2 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 9 +- hotspot/src/share/vm/oops/instanceKlass.hpp | 2 +- hotspot/src/share/vm/oops/klass.cpp | 4 +- hotspot/src/share/vm/oops/klass.hpp | 2 +- hotspot/src/share/vm/oops/markOop.cpp | 3 +- hotspot/src/share/vm/oops/methodOop.cpp | 2 +- hotspot/src/share/vm/prims/methodHandles.cpp | 178 +++++++++++++----- hotspot/src/share/vm/prims/methodHandles.hpp | 40 ++-- 12 files changed, 274 insertions(+), 120 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp index a45af4ad321..a682a81b833 100644 --- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp +++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp @@ -271,9 +271,15 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm, void trace_method_handle_stub(const char* adaptername, oopDesc* mh, intptr_t* entry_sp, - intptr_t* saved_sp) { + intptr_t* saved_sp, + intptr_t* saved_bp) { // called as a leaf from native code: do not block the JVM! - printf("MH %s "PTR_FORMAT" "PTR_FORMAT" "INTX_FORMAT"\n", adaptername, (void*)mh, entry_sp, entry_sp - saved_sp); + intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset]; + intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset]; + printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n", + adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp); + if (last_sp != saved_sp) + printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp); } #endif //PRODUCT @@ -293,6 +299,10 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan Register rbx_temp = rbx; Register rdx_temp = rdx; + // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls) + // and gen_c2i_adapter (from compiled calls): + Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi); + guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); // some handy addresses @@ -315,6 +325,8 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan assert(tag_offset = wordSize, "stack grows as expected"); } + const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); + if (have_entry(ek)) { __ nop(); // empty stubs make SG sick return; @@ -328,45 +340,65 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan __ push(rax); __ push(rbx); __ push(rcx); __ push(rdx); __ push(rsi); __ push(rdi); __ lea(rax, Address(rsp, wordSize*6)); // entry_sp // arguments: + __ push(rbp); // interpreter frame pointer __ push(rsi); // saved_sp __ push(rax); // entry_sp __ push(rcx); // mh __ push(rcx); __ movptr(Address(rsp, 0), (intptr_t)entry_name(ek)); - __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 4); + __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 5); __ pop(rdi); __ pop(rsi); __ pop(rdx); __ pop(rcx); __ pop(rbx); __ pop(rax); } #endif //PRODUCT switch ((int) ek) { - case _check_mtype: + case _raise_exception: { - // this stub is special, because it requires a live mtype argument - Register rax_mtype = rax; + // Not a real MH entry, but rather shared code for raising an exception. + // Extra local arguments are pushed on stack, as required type at TOS+8, + // failing object (or NULL) at TOS+4, failing bytecode type at TOS. + // Beyond those local arguments are the PC, of course. + Register rdx_code = rdx_temp; + Register rcx_fail = rcx_recv; + Register rax_want = rax_argslot; + Register rdi_pc = rdi; + __ pop(rdx_code); // TOS+0 + __ pop(rcx_fail); // TOS+4 + __ pop(rax_want); // TOS+8 + __ pop(rdi_pc); // caller PC - // emit WrongMethodType path first, to enable jccb back-branch - Label wrong_method_type; - __ bind(wrong_method_type); - __ movptr(rdx_temp, ExternalAddress((address) &_entries[_wrong_method_type])); - __ jmp(Address(rdx_temp, MethodHandleEntry::from_interpreted_entry_offset_in_bytes())); - __ hlt(); + __ mov(rsp, rsi); // cut the stack back to where the caller started - interp_entry = __ pc(); - __ check_method_handle_type(rax_mtype, rcx_recv, rdx_temp, wrong_method_type); - // now rax_mtype is dead; subsequent stubs will use it as a temp + // Repush the arguments as if coming from the interpreter. + if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_INT)); + __ push(rdx_code); + if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT)); + __ push(rcx_fail); + if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT)); + __ push(rax_want); - __ jump_to_method_handle_entry(rcx_recv, rdx_temp); - } - break; + Register rbx_method = rbx_temp; + Label no_method; + // FIXME: fill in _raise_exception_method with a suitable sun.dyn method + __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); + __ testptr(rbx_method, rbx_method); + __ jcc(Assembler::zero, no_method); + int jobject_oop_offset = 0; + __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject + __ testptr(rbx_method, rbx_method); + __ jcc(Assembler::zero, no_method); + __ verify_oop(rbx_method); + __ push(rdi_pc); // and restore caller PC + __ jmp(rbx_method_fie); - case _wrong_method_type: - { - // this stub is special, because it requires a live mtype argument - Register rax_mtype = rax; - - interp_entry = __ pc(); - __ push(rax_mtype); // required mtype - __ push(rcx_recv); // random mh (1st stacked argument) + // If we get here, the Java runtime did not do its job of creating the exception. + // Do something that is at least causes a valid throw from the interpreter. + __ bind(no_method); + __ pop(rax_want); + if (TaggedStackInterpreter) __ pop(rcx_fail); + __ pop(rcx_fail); + __ push(rax_want); + __ push(rcx_fail); __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); } break; @@ -442,7 +474,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan __ load_klass(rax_klass, rcx_recv); __ verify_oop(rax_klass); - Register rcx_temp = rcx_recv; + Register rdi_temp = rdi; Register rbx_method = rbx_index; // get interface klass @@ -451,7 +483,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan __ lookup_interface_method(rax_klass, rdx_intf, // note: next two args must be the same: rbx_index, rbx_method, - rcx_temp, + rdi_temp, no_such_interface); __ verify_oop(rbx_method); @@ -461,7 +493,10 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan __ bind(no_such_interface); // Throw an exception. // For historical reasons, it will be IncompatibleClassChangeError. - __ should_not_reach_here(); // %%% FIXME NYI + __ pushptr(Address(rdx_intf, java_mirror_offset)); // required interface + __ push(rcx_recv); // bad receiver + __ push((int)Bytecodes::_invokeinterface); // who is complaining? + __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); } break; @@ -524,6 +559,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan break; case _adapter_retype_only: + case _adapter_retype_raw: // immediately jump to the next MH layer: __ movptr(rcx_recv, rcx_mh_vmtarget); __ verify_oop(rcx_recv); @@ -545,10 +581,6 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object! __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); - // get the new MH: - __ movptr(rcx_recv, rcx_mh_vmtarget); - // (now we are done with the old MH) - Label done; __ movptr(rdx_temp, vmarg); __ testl(rdx_temp, rdx_temp); @@ -558,17 +590,23 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan // live at this point: // - rbx_klass: klass required by the target method // - rdx_temp: argument klass to test - // - rcx_recv: method handle to invoke (after cast succeeds) + // - rcx_recv: adapter method handle __ check_klass_subtype(rdx_temp, rbx_klass, rax_argslot, done); // If we get here, the type check failed! // Call the wrong_method_type stub, passing the failing argument type in rax. Register rax_mtype = rax_argslot; - __ push(rbx_klass); // missed klass (required type) - __ push(rdx_temp); // bad actual type (1st stacked argument) - __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); + __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field + __ movptr(rdx_temp, vmarg); + + __ pushptr(rcx_amh_argument); // required class + __ push(rdx_temp); // bad object + __ push((int)Bytecodes::_checkcast); // who is complaining? + __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); __ bind(done); + // get the new MH: + __ movptr(rcx_recv, rcx_mh_vmtarget); __ jump_to_method_handle_entry(rcx_recv, rdx_temp); } break; @@ -1107,11 +1145,17 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan __ bind(bad_array_klass); UNPUSH_RSI_RDI; - __ stop("bad array klass NYI"); + __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type + __ pushptr(vmarg); // bad array + __ push((int)Bytecodes::_aaload); // who is complaining? + __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); __ bind(bad_array_length); UNPUSH_RSI_RDI; - __ stop("bad array length NYI"); + __ push(rcx_recv); // AMH requiring a certain length + __ pushptr(vmarg); // bad array + __ push((int)Bytecodes::_arraylength); // who is complaining? + __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); #undef UNPUSH_RSI_RDI } diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp index 1f20ee4b894..b78f0e2a066 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp @@ -92,8 +92,7 @@ address TemplateInterpreterGenerator::generate_ClassCastException_handler() { return entry; } -// Arguments are: required type at TOS+8, failing object (or NULL) at TOS+4. -// pc at TOS (just for debugging) +// Arguments are: required type at TOS+4, failing object (or NULL) at TOS. address TemplateInterpreterGenerator::generate_WrongMethodType_handler() { address entry = __ pc(); diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 51e28171903..048fba8d4b0 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -903,19 +903,20 @@ class sun_dyn_AdapterMethodHandle: public sun_dyn_BoundMethodHandle { // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants): enum { OP_RETYPE_ONLY = 0x0, // no argument changes; straight retype - OP_CHECK_CAST = 0x1, // ref-to-ref conversion; requires a Class argument - OP_PRIM_TO_PRIM = 0x2, // converts from one primitive to another - OP_REF_TO_PRIM = 0x3, // unboxes a wrapper to produce a primitive - OP_PRIM_TO_REF = 0x4, // boxes a primitive into a wrapper (NYI) - OP_SWAP_ARGS = 0x5, // swap arguments (vminfo is 2nd arg) - OP_ROT_ARGS = 0x6, // rotate arguments (vminfo is displaced arg) - OP_DUP_ARGS = 0x7, // duplicates one or more arguments (at TOS) - OP_DROP_ARGS = 0x8, // remove one or more argument slots - OP_COLLECT_ARGS = 0x9, // combine one or more arguments into a varargs (NYI) - OP_SPREAD_ARGS = 0xA, // expand in place a varargs array (of known size) - OP_FLYBY = 0xB, // operate first on reified argument list (NYI) - OP_RICOCHET = 0xC, // run an adapter chain on the return value (NYI) - CONV_OP_LIMIT = 0xD, // limit of CONV_OP enumeration + OP_RETYPE_RAW = 0x1, // straight retype, trusted (void->int, Object->T) + OP_CHECK_CAST = 0x2, // ref-to-ref conversion; requires a Class argument + OP_PRIM_TO_PRIM = 0x3, // converts from one primitive to another + OP_REF_TO_PRIM = 0x4, // unboxes a wrapper to produce a primitive + OP_PRIM_TO_REF = 0x5, // boxes a primitive into a wrapper (NYI) + OP_SWAP_ARGS = 0x6, // swap arguments (vminfo is 2nd arg) + OP_ROT_ARGS = 0x7, // rotate arguments (vminfo is displaced arg) + OP_DUP_ARGS = 0x8, // duplicates one or more arguments (at TOS) + OP_DROP_ARGS = 0x9, // remove one or more argument slots + OP_COLLECT_ARGS = 0xA, // combine one or more arguments into a varargs (NYI) + OP_SPREAD_ARGS = 0xB, // expand in place a varargs array (of known size) + OP_FLYBY = 0xC, // operate first on reified argument list (NYI) + OP_RICOCHET = 0xD, // run an adapter chain on the return value (NYI) + CONV_OP_LIMIT = 0xE, // limit of CONV_OP enumeration CONV_OP_MASK = 0xF00, // this nybble contains the conversion op field CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index a0e1432c315..5598c9fcfb3 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -1963,7 +1963,7 @@ void SystemDictionary::initialize_preloaded_classes(TRAPS) { WKID meth_group_end = WK_KLASS_ENUM_NAME(WrongMethodTypeException_klass); initialize_wk_klasses_until(meth_group_start, scan, CHECK); if (EnableMethodHandles) { - initialize_wk_klasses_through(meth_group_start, scan, CHECK); + initialize_wk_klasses_through(meth_group_end, scan, CHECK); } if (_well_known_klasses[meth_group_start] == NULL) { // Skip the rest of the method handle classes, if MethodHandle is not loaded. diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 7e5b0ebf17d..aaa2bfe876e 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -1900,7 +1900,7 @@ void instanceKlass::release_C_heap_structures() { } } -char* instanceKlass::signature_name() const { +const char* instanceKlass::signature_name() const { const char* src = (const char*) (name()->as_C_string()); const int src_length = (int)strlen(src); char* dest = NEW_RESOURCE_ARRAY(char, src_length + 3); @@ -2259,6 +2259,10 @@ void instanceKlass::oop_print_on(oop obj, outputStream* st) { st->print(BULLET"fake entry for array: "); array_klass->print_value_on(st); st->cr(); + } else if (as_klassOop() == SystemDictionary::MethodType_klass()) { + st->print(BULLET"signature: "); + java_dyn_MethodType::print_signature(obj, st); + st->cr(); } } @@ -2284,6 +2288,9 @@ void instanceKlass::oop_print_value_on(oop obj, outputStream* st) { const char* tname = type2name(java_lang_Class::primitive_type(obj)); st->print("%s", tname ? tname : "type?"); } + } else if (as_klassOop() == SystemDictionary::MethodType_klass()) { + st->print(" = "); + java_dyn_MethodType::print_signature(obj, st); } else if (java_lang_boxing_object::is_instance(obj)) { st->print(" = "); java_lang_boxing_object::print(obj, st); diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index bb992170e02..9147892b1ea 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -722,7 +722,7 @@ class instanceKlass: public Klass { #endif // SERIALGC // Naming - char* signature_name() const; + const char* signature_name() const; // Iterators int oop_oop_iterate(oop obj, OopClosure* blk) { diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index 63a342e5b67..a842709649e 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -496,11 +496,13 @@ const char* Klass::external_name() const { return result; } } + if (name() == NULL) return ""; return name()->as_klass_external_name(); } -char* Klass::signature_name() const { +const char* Klass::signature_name() const { + if (name() == NULL) return ""; return name()->as_C_string(); } diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp index 9ed07d2fb81..c4436d6554f 100644 --- a/hotspot/src/share/vm/oops/klass.hpp +++ b/hotspot/src/share/vm/oops/klass.hpp @@ -546,7 +546,7 @@ class Klass : public Klass_vtbl { // For arrays, this returns the name of the element with a leading '['. // For classes, this returns the name with a leading 'L' and a trailing ';' // and the package separators as '/'. - virtual char* signature_name() const; + virtual const char* signature_name() const; // garbage collection support virtual void oop_follow_contents(oop obj) = 0; diff --git a/hotspot/src/share/vm/oops/markOop.cpp b/hotspot/src/share/vm/oops/markOop.cpp index ac1a99c2cd7..0bec23f9034 100644 --- a/hotspot/src/share/vm/oops/markOop.cpp +++ b/hotspot/src/share/vm/oops/markOop.cpp @@ -31,8 +31,9 @@ void markOopDesc::print_on(outputStream* st) const { st->print("locked(0x%lx)->", value()); markOop(*(markOop*)value())->print_on(st); } else { - assert(is_unlocked(), "just checking"); + assert(is_unlocked() || has_bias_pattern(), "just checking"); st->print("mark("); + if (has_bias_pattern()) st->print("biased,"); st->print("hash %#lx,", hash()); st->print("age %d)", age()); } diff --git a/hotspot/src/share/vm/oops/methodOop.cpp b/hotspot/src/share/vm/oops/methodOop.cpp index e68c289510c..cd575e5c488 100644 --- a/hotspot/src/share/vm/oops/methodOop.cpp +++ b/hotspot/src/share/vm/oops/methodOop.cpp @@ -881,7 +881,7 @@ methodHandle methodOopDesc::make_invoke_method(KlassHandle holder, assert((oop)p == method_type(), "pointer chase is correct"); #endif - if (TraceMethodHandles) + if (TraceMethodHandles && (Verbose || WizardMode)) m->print_on(tty); return m; diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp index f194644715e..b5910f21d37 100644 --- a/hotspot/src/share/vm/prims/methodHandles.cpp +++ b/hotspot/src/share/vm/prims/methodHandles.cpp @@ -33,8 +33,7 @@ bool MethodHandles::_enabled = false; // set true after successful native linkag MethodHandleEntry* MethodHandles::_entries[MethodHandles::_EK_LIMIT] = {NULL}; const char* MethodHandles::_entry_names[_EK_LIMIT+1] = { - "check_mtype", - "wrong_method_type", // what happens when there is a type mismatch + "raise_exception", "invokestatic", // how a MH emulates invokestatic "invokespecial", // ditto for the other invokes... "invokevirtual", @@ -48,6 +47,7 @@ const char* MethodHandles::_entry_names[_EK_LIMIT+1] = { // starting at _adapter_mh_first: "adapter_retype_only", // these are for AMH... + "adapter_retype_raw", "adapter_check_cast", "adapter_prim_to_prim", "adapter_ref_to_prim", @@ -82,6 +82,8 @@ const char* MethodHandles::_entry_names[_EK_LIMIT+1] = { NULL }; +jobject MethodHandles::_raise_exception_method; + #ifdef ASSERT bool MethodHandles::spot_check_entry_names() { assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), ""); @@ -157,7 +159,8 @@ methodOop MethodHandles::decode_DirectMethodHandle(oop mh, klassOop& receiver_li } methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { - assert(mh->klass() == SystemDictionary::BoundMethodHandle_klass(), ""); + assert(sun_dyn_BoundMethodHandle::is_instance(mh), ""); + assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), ""); for (oop bmh = mh;;) { // Bound MHs can be stacked to bind several arguments. oop target = java_dyn_MethodHandle::vmtarget(bmh); @@ -174,10 +177,9 @@ methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_lim } else { // Optimized case: binding a receiver to a non-dispatched DMH // short-circuits directly to the methodOop. + // (It might be another argument besides a receiver also.) assert(target->is_method(), "must be a simple method"); methodOop m = (methodOop) target; - DEBUG_ONLY(int argslot = sun_dyn_BoundMethodHandle::vmargslot(bmh)); - assert(argslot == m->size_of_parameters() - 1, "must be initial argument (receiver)"); decode_flags_result |= MethodHandles::_dmf_binds_method; return m; } @@ -214,6 +216,9 @@ methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_re return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); } else if (mhk == SystemDictionary::AdapterMethodHandle_klass()) { return decode_AdapterMethodHandle(mh, receiver_limit_result, decode_flags_result); + } else if (sun_dyn_BoundMethodHandle::is_subclass(mhk)) { + // could be a JavaMethodHandle (but not an adapter MH) + return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); } else { assert(false, "cannot parse this MH"); return NULL; // random MH? @@ -366,7 +371,13 @@ methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_r oop vmtarget = sun_dyn_MemberName::vmtarget(mname); int vmindex = sun_dyn_MemberName::vmindex(mname); if (vmindex == VM_INDEX_UNINITIALIZED) return NULL; // not resolved - return decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); + methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); + oop clazz = sun_dyn_MemberName::clazz(mname); + if (clazz != NULL && java_lang_Class::is_instance(clazz)) { + klassOop klass = java_lang_Class::as_klassOop(clazz); + if (klass != NULL) receiver_limit_result = klass; + } + return m; } // An unresolved member name is a mere symbolic reference. @@ -789,6 +800,30 @@ oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), msg); } +static const char* always_null_names[] = { + "java/lang/Void", + "java/lang/Null", + //"java/lang/Nothing", + "sun/dyn/empty/Empty", + NULL +}; + +static bool is_always_null_type(klassOop klass) { + if (!Klass::cast(klass)->oop_is_instance()) return false; + instanceKlass* ik = instanceKlass::cast(klass); + // Must be on the boot class path: + if (ik->class_loader() != NULL) return false; + // Check the name. + symbolOop name = ik->name(); + for (int i = 0; ; i++) { + const char* test_name = always_null_names[i]; + if (test_name == NULL) break; + if (name->equals(test_name, (int) strlen(test_name))) + return true; + } + return false; +} + bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) { if (src == dst || dst == SystemDictionary::object_klass()) return false; // quickest checks @@ -805,6 +840,12 @@ bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) { //srck = Klass::cast(SystemDictionary::object_klass()); return true; } + if (is_always_null_type(src)) { + // some source types are known to be never instantiated; + // they represent references which are always null + // such null references never fail to convert safely + return false; + } return !srck->is_subclass_of(dstk->as_klassOop()); } @@ -814,9 +855,15 @@ static oop object_java_mirror() { bool MethodHandles::same_basic_type_for_arguments(BasicType src, BasicType dst, + bool raw, bool for_return) { - // return values can always be forgotten: - if (for_return && dst == T_VOID) return true; + if (for_return) { + // return values can always be forgotten: + if (dst == T_VOID) return true; + if (src == T_VOID) return raw && (dst == T_INT); + // We allow caller to receive a garbage int, which is harmless. + // This trick is pulled by trusted code (see VerifyType.canPassRaw). + } assert(src != T_VOID && dst != T_VOID, "should not be here"); if (src == dst) return true; if (type2size[src] != type2size[dst]) return false; @@ -929,8 +976,8 @@ void MethodHandles::verify_method_type(methodHandle m, const char* err = NULL; int first_ptype_pos = m_needs_receiver ? 1 : 0; - if (has_bound_recv && err == NULL) { - first_ptype_pos -= 1; + if (has_bound_recv) { + first_ptype_pos -= 1; // ptypes do not include the bound argument; start earlier in them if (m_needs_receiver && bound_recv_type.is_null()) { err = "bound receiver is not an object"; goto die; } } @@ -939,10 +986,10 @@ void MethodHandles::verify_method_type(methodHandle m, objArrayOop ptypes = java_dyn_MethodType::ptypes(mtype()); if (ptypes->length() < first_ptype_pos) { err = "receiver argument is missing"; goto die; } - if (first_ptype_pos == -1) + if (has_bound_recv) err = check_method_receiver(m(), bound_recv_type->as_klassOop()); else - err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(0))); + err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(first_ptype_pos-1))); if (err != NULL) goto die; } @@ -983,7 +1030,8 @@ const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, int insert_argnum, oop insert_type, int change_argnum, oop change_type, int delete_argnum, - oop dst_mtype, int dst_beg, int dst_end) { + oop dst_mtype, int dst_beg, int dst_end, + bool raw) { objArrayOop src_ptypes = java_dyn_MethodType::ptypes(src_mtype); objArrayOop dst_ptypes = java_dyn_MethodType::ptypes(dst_mtype); @@ -1042,7 +1090,7 @@ const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, if (src_type != dst_type) { if (src_type == NULL) return "not enough arguments"; if (dst_type == NULL) return "too many arguments"; - err = check_argument_type_change(src_type, dst_type, dst_idx); + err = check_argument_type_change(src_type, dst_type, dst_idx, raw); if (err != NULL) return err; } } @@ -1051,7 +1099,7 @@ const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, oop src_rtype = java_dyn_MethodType::rtype(src_mtype); oop dst_rtype = java_dyn_MethodType::rtype(dst_mtype); if (src_rtype != dst_rtype) { - err = check_return_type_change(dst_rtype, src_rtype); // note reversal! + err = check_return_type_change(dst_rtype, src_rtype, raw); // note reversal! if (err != NULL) return err; } @@ -1061,38 +1109,45 @@ const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, const char* MethodHandles::check_argument_type_change(BasicType src_type, - klassOop src_klass, - BasicType dst_type, - klassOop dst_klass, - int argnum) { + klassOop src_klass, + BasicType dst_type, + klassOop dst_klass, + int argnum, + bool raw) { const char* err = NULL; + bool for_return = (argnum < 0); // just in case: if (src_type == T_ARRAY) src_type = T_OBJECT; if (dst_type == T_ARRAY) dst_type = T_OBJECT; // Produce some nice messages if VerifyMethodHandles is turned on: - if (!same_basic_type_for_arguments(src_type, dst_type, (argnum < 0))) { + if (!same_basic_type_for_arguments(src_type, dst_type, raw, for_return)) { if (src_type == T_OBJECT) { + if (raw && dst_type == T_INT && is_always_null_type(src_klass)) + return NULL; // OK to convert a null pointer to a garbage int err = ((argnum >= 0) ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s" : "type mismatch: returning a %s, but caller expects primitive %s"); } else if (dst_type == T_OBJECT) { - err = ((argnum < 0) + err = ((argnum >= 0) ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s" : "type mismatch: returning a primitive %s, but caller expects %s"); } else { - err = ((argnum < 0) + err = ((argnum >= 0) ? "type mismatch: passing a %s for method argument #%d, which expects %s" : "type mismatch: returning a %s, but caller expects %s"); } - } else if (src_type == T_OBJECT && class_cast_needed(src_klass, dst_klass)) { + } else if (src_type == T_OBJECT && dst_type == T_OBJECT && + class_cast_needed(src_klass, dst_klass)) { if (!class_cast_needed(dst_klass, src_klass)) { - err = ((argnum < 0) + if (raw) + return NULL; // reverse cast is OK; the MH target is trusted to enforce it + err = ((argnum >= 0) ? "cast required: passing a %s for method argument #%d, which expects %s" : "cast required: returning a %s, but caller expects %s"); } else { - err = ((argnum < 0) + err = ((argnum >= 0) ? "reference mismatch: passing a %s for method argument #%d, which expects %s" : "reference mismatch: returning a %s, but caller expects %s"); } @@ -1429,10 +1484,10 @@ void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnu assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots"); assert(slots_pushed <= MethodHandlePushLimit, ""); } else { - int prev_pushes = decode_MethodHandle_stack_pushes(target()); - assert(this_pushes == slots_pushed + prev_pushes, "BMH stack motion must be correct"); + int target_pushes = decode_MethodHandle_stack_pushes(target()); + assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct"); // do not blow the stack; use a Java-based adapter if this limit is exceeded - if (slots_pushed + prev_pushes > MethodHandlePushLimit) + if (slots_pushed + target_pushes > MethodHandlePushLimit) err = "too many bound parameters"; } } @@ -1588,6 +1643,11 @@ void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) { if (err == NULL) { // Check that the src/dest types are supplied if needed. switch (ek) { + case _adapter_check_cast: + if (src != T_OBJECT || dest != T_OBJECT) { + err = "adapter requires object src/dest conversion subfields"; + } + break; case _adapter_prim_to_prim: if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) { err = "adapter requires primitive src/dest conversion subfields"; break; @@ -1616,9 +1676,9 @@ void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) { err = "adapter requires src/dest conversion subfields for swap"; break; } int swap_size = type2size[src]; - oop src_mtype = sun_dyn_AdapterMethodHandle::type(target()); - oop dest_mtype = sun_dyn_AdapterMethodHandle::type(mh()); - int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(src_mtype); + oop src_mtype = sun_dyn_AdapterMethodHandle::type(mh()); + oop dest_mtype = sun_dyn_AdapterMethodHandle::type(target()); + int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(target()); int src_slot = argslot; int dest_slot = vminfo; bool rotate_up = (src_slot > dest_slot); // upward rotation @@ -1729,22 +1789,22 @@ void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) { // Make sure this adapter does not push too deeply. int slots_pushed = stack_move / stack_move_unit(); int this_vmslots = java_dyn_MethodHandle::vmslots(mh()); - int prev_vmslots = java_dyn_MethodHandle::vmslots(target()); - if (slots_pushed != (this_vmslots - prev_vmslots)) { + int target_vmslots = java_dyn_MethodHandle::vmslots(target()); + if (slots_pushed != (target_vmslots - this_vmslots)) { err = "stack_move inconsistent with previous and current MethodType vmslots"; } else if (slots_pushed > 0) { // verify stack_move against MethodHandlePushLimit - int prev_pushes = decode_MethodHandle_stack_pushes(target()); + int target_pushes = decode_MethodHandle_stack_pushes(target()); // do not blow the stack; use a Java-based adapter if this limit is exceeded - if (slots_pushed + prev_pushes > MethodHandlePushLimit) { + if (slots_pushed + target_pushes > MethodHandlePushLimit) { err = "adapter pushes too many parameters"; } } // While we're at it, check that the stack motion decoder works: - DEBUG_ONLY(int prev_pushes = decode_MethodHandle_stack_pushes(target())); + DEBUG_ONLY(int target_pushes = decode_MethodHandle_stack_pushes(target())); DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh())); - assert(this_pushes == slots_pushed + prev_pushes, "AMH stack motion must be correct"); + assert(this_pushes == slots_pushed + target_pushes, "AMH stack motion must be correct"); } if (err == NULL && vminfo != 0) { @@ -1761,7 +1821,11 @@ void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) { if (err == NULL) { switch (ek) { case _adapter_retype_only: - err = check_method_type_passthrough(src_mtype(), dst_mtype()); + err = check_method_type_passthrough(src_mtype(), dst_mtype(), false); + break; + + case _adapter_retype_raw: + err = check_method_type_passthrough(src_mtype(), dst_mtype(), true); break; case _adapter_check_cast: @@ -1821,6 +1885,7 @@ void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnu // Now it's time to finish the case analysis and pick a MethodHandleEntry. switch (ek_orig) { case _adapter_retype_only: + case _adapter_retype_raw: case _adapter_check_cast: case _adapter_dup_args: case _adapter_drop_args: @@ -1888,8 +1953,7 @@ void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnu case _adapter_rot_args: { int swap_slots = type2size[src]; - oop mtype = sun_dyn_AdapterMethodHandle::type(mh()); - int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(mtype); + int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(mh()); int src_slot = argslot; int dest_slot = vminfo; int rotate = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1; @@ -2133,7 +2197,7 @@ JVM_ENTRY(jint, MHI_getConstant(JNIEnv *env, jobject igcls, jint which)) { guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF, "MethodHandlePushLimit parameter must be in valid range"); return MethodHandlePushLimit; - case MethodHandles::GC_JVM_STACK_MOVE_LIMIT: + case MethodHandles::GC_JVM_STACK_MOVE_UNIT: // return number of words per slot, signed according to stack direction return MethodHandles::stack_move_unit(); } @@ -2144,7 +2208,7 @@ JVM_END #ifndef PRODUCT #define EACH_NAMED_CON(template) \ template(MethodHandles,GC_JVM_PUSH_LIMIT) \ - template(MethodHandles,GC_JVM_STACK_MOVE_LIMIT) \ + template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) \ template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \ template(MethodHandles,ETF_DIRECT_HANDLE) \ template(MethodHandles,ETF_METHOD_NAME) \ @@ -2157,6 +2221,7 @@ JVM_END template(sun_dyn_MemberName,MN_SEARCH_INTERFACES) \ template(sun_dyn_MemberName,VM_INDEX_UNINITIALIZED) \ template(sun_dyn_AdapterMethodHandle,OP_RETYPE_ONLY) \ + template(sun_dyn_AdapterMethodHandle,OP_RETYPE_RAW) \ template(sun_dyn_AdapterMethodHandle,OP_CHECK_CAST) \ template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_PRIM) \ template(sun_dyn_AdapterMethodHandle,OP_REF_TO_PRIM) \ @@ -2345,10 +2410,12 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) // note: this explicit warning-producing stuff will be replaced by auto-detection of the JSR 292 classes if (!EnableMethodHandles) { - warning("JSR 292 method handles are disabled in this JVM. Use -XX:+EnableMethodHandles to enable."); + warning("JSR 292 method handles are disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles to enable."); return; // bind nothing } + bool enable_MH = true; + { ThreadToNativeFromVM ttnfv(thread); @@ -2356,14 +2423,33 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) if (env->ExceptionOccurred()) { MethodHandles::set_enabled(false); warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); + enable_MH = false; env->ExceptionClear(); - } else { - MethodHandles::set_enabled(true); } } + if (enable_MH) { + KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass(); + if (MHI_klass.not_null()) { + symbolHandle raiseException_name = oopFactory::new_symbol_handle("raiseException", CHECK); + symbolHandle raiseException_sig = oopFactory::new_symbol_handle("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); + methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop()) + ->find_method(raiseException_name(), raiseException_sig()); + if (raiseException_method != NULL && raiseException_method->is_static()) { + MethodHandles::set_raise_exception_method(raiseException_method); + } else { + warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); + enable_MH = false; + } + } + } + + if (enable_MH) { + MethodHandles::set_enabled(true); + } + if (!EnableInvokeDynamic) { - warning("JSR 292 invokedynamic is disabled in this JVM. Use -XX:+EnableInvokeDynamic to enable."); + warning("JSR 292 invokedynamic is disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic to enable."); return; // bind nothing } diff --git a/hotspot/src/share/vm/prims/methodHandles.hpp b/hotspot/src/share/vm/prims/methodHandles.hpp index 5f660e743e4..fea29650b5c 100644 --- a/hotspot/src/share/vm/prims/methodHandles.hpp +++ b/hotspot/src/share/vm/prims/methodHandles.hpp @@ -32,8 +32,7 @@ class MethodHandles: AllStatic { // See also javaClasses for layouts java_dyn_Method{Handle,Type,Type::Form}. public: enum EntryKind { - _check_mtype, // how a caller calls a MH - _wrong_method_type, // what happens when there is a type mismatch + _raise_exception, // stub for error generation from other stubs _invokestatic_mh, // how a MH emulates invokestatic _invokespecial_mh, // ditto for the other invokes... _invokevirtual_mh, @@ -47,6 +46,7 @@ class MethodHandles: AllStatic { _adapter_mh_first, // adapter sequence goes here... _adapter_retype_only = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY, + _adapter_retype_raw = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW, _adapter_check_cast = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_CHECK_CAST, _adapter_prim_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM, _adapter_ref_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM, @@ -113,6 +113,8 @@ class MethodHandles: AllStatic { static bool _enabled; static MethodHandleEntry* _entries[_EK_LIMIT]; static const char* _entry_names[_EK_LIMIT+1]; + static jobject _raise_exception_method; + static bool ek_valid(EntryKind ek) { return (uint)ek < (uint)_EK_LIMIT; } static bool conv_op_valid(int op) { return (uint)op < (uint)CONV_OP_LIMIT; } @@ -131,6 +133,16 @@ class MethodHandles: AllStatic { _entries[ek] = me; } + static methodOop raise_exception_method() { + oop rem = JNIHandles::resolve(_raise_exception_method); + assert(rem == NULL || rem->is_method(), ""); + return (methodOop) rem; + } + static void set_raise_exception_method(methodOop rem) { + assert(_raise_exception_method == NULL, ""); + _raise_exception_method = JNIHandles::make_global(Handle(rem)); + } + static jint adapter_conversion(int conv_op, BasicType src, BasicType dest, int stack_move = 0, int vminfo = 0) { assert(conv_op_valid(conv_op), "oob"); @@ -243,7 +255,7 @@ class MethodHandles: AllStatic { enum { // format of query to getConstant: GC_JVM_PUSH_LIMIT = 0, - GC_JVM_STACK_MOVE_LIMIT = 1, + GC_JVM_STACK_MOVE_UNIT = 1, // format of result from getTarget / encode_target: ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method) @@ -261,7 +273,8 @@ class MethodHandles: AllStatic { int insert_argnum, oop insert_type, int change_argnum, oop change_type, int delete_argnum, - oop dst_mtype, int dst_beg, int dst_end); + oop dst_mtype, int dst_beg, int dst_end, + bool raw = false); static const char* check_method_type_insertion(oop src_mtype, int insert_argnum, oop insert_type, oop dst_mtype) { @@ -278,29 +291,29 @@ class MethodHandles: AllStatic { change_argnum, change_type, -1, dst_mtype, 0, -1); } - static const char* check_method_type_passthrough(oop src_mtype, oop dst_mtype) { + static const char* check_method_type_passthrough(oop src_mtype, oop dst_mtype, bool raw) { oop no_ref = NULL; return check_method_type_change(src_mtype, 0, -1, -1, no_ref, -1, no_ref, -1, - dst_mtype, 0, -1); + dst_mtype, 0, -1, raw); } // These checkers operate on pairs of argument or return types: static const char* check_argument_type_change(BasicType src_type, klassOop src_klass, BasicType dst_type, klassOop dst_klass, - int argnum); + int argnum, bool raw = false); static const char* check_argument_type_change(oop src_type, oop dst_type, - int argnum) { + int argnum, bool raw = false) { klassOop src_klass = NULL, dst_klass = NULL; BasicType src_bt = java_lang_Class::as_BasicType(src_type, &src_klass); BasicType dst_bt = java_lang_Class::as_BasicType(dst_type, &dst_klass); return check_argument_type_change(src_bt, src_klass, - dst_bt, dst_klass, argnum); + dst_bt, dst_klass, argnum, raw); } - static const char* check_return_type_change(oop src_type, oop dst_type) { - return check_argument_type_change(src_type, dst_type, -1); + static const char* check_return_type_change(oop src_type, oop dst_type, bool raw = false) { + return check_argument_type_change(src_type, dst_type, -1, raw); } static const char* check_return_type_change(BasicType src_type, klassOop src_klass, @@ -357,9 +370,10 @@ class MethodHandles: AllStatic { TRAPS); static bool same_basic_type_for_arguments(BasicType src, BasicType dst, + bool raw = false, bool for_return = false); - static bool same_basic_type_for_returns(BasicType src, BasicType dst) { - return same_basic_type_for_arguments(src, dst, true); + static bool same_basic_type_for_returns(BasicType src, BasicType dst, bool raw = false) { + return same_basic_type_for_arguments(src, dst, raw, true); } enum { // arg_mask values From a77b6a72e03c2b151af3ecab5e73c1c759fd46ad Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Mon, 19 Oct 2009 16:06:41 +0400 Subject: [PATCH 077/172] 6891483: XToolkit.getEnv() checks for NULL on a wrong symbol Reviewed-by: dcherepanov --- jdk/src/solaris/native/sun/xawt/XToolkit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/solaris/native/sun/xawt/XToolkit.c b/jdk/src/solaris/native/sun/xawt/XToolkit.c index 6ce5876c544..a4323b31995 100644 --- a/jdk/src/solaris/native/sun/xawt/XToolkit.c +++ b/jdk/src/solaris/native/sun/xawt/XToolkit.c @@ -677,7 +677,7 @@ JNIEXPORT jstring JNICALL Java_sun_awt_X11_XToolkit_getEnv jstring ret = NULL; keystr = JNU_GetStringPlatformChars(env, key, NULL); - if (key) { + if (keystr) { ptr = getenv(keystr); if (ptr) { ret = JNU_NewStringPlatform(env, (const char *) ptr); From 6e476efa4ae270ccf518b7146de6c1f82a84b795 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Mon, 19 Oct 2009 19:58:38 +0100 Subject: [PATCH 078/172] 6892710: (file) test/java/nio/file/Path/CheckPermissions.java fails in samevm mode Reviewed-by: ohair --- jdk/test/java/nio/file/Files/ContentType.java | 2 +- jdk/test/java/nio/file/Path/CheckPermissions.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/jdk/test/java/nio/file/Files/ContentType.java b/jdk/test/java/nio/file/Files/ContentType.java index fdbb9014ef6..3cea26539f8 100644 --- a/jdk/test/java/nio/file/Files/ContentType.java +++ b/jdk/test/java/nio/file/Files/ContentType.java @@ -26,7 +26,7 @@ * @summary Unit test for probeContentType method * @library .. * @build ContentType SimpleFileTypeDetector - * @run main ContentType + * @run main/othervm ContentType */ import java.nio.file.*; diff --git a/jdk/test/java/nio/file/Path/CheckPermissions.java b/jdk/test/java/nio/file/Path/CheckPermissions.java index a8aef0f91f2..9e0f796afc7 100644 --- a/jdk/test/java/nio/file/Path/CheckPermissions.java +++ b/jdk/test/java/nio/file/Path/CheckPermissions.java @@ -25,6 +25,8 @@ * @bug 6866804 * @summary Unit test for java.nio.file.Path * @library .. + * @build CheckPermissions + * @run main/othervm CheckPermissions */ import java.nio.ByteBuffer; From 1ff76e393896377f5d64eb27de14516fcf4cd32c Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Mon, 19 Oct 2009 19:59:22 +0100 Subject: [PATCH 079/172] 6892711: (file) test/java/nio/file/Path/CopyAndMove.java fails on Windows 2000 Reviewed-by: ohair --- jdk/test/java/nio/file/Path/CopyAndMove.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jdk/test/java/nio/file/Path/CopyAndMove.java b/jdk/test/java/nio/file/Path/CopyAndMove.java index 39ac66871f5..5894b2894f2 100644 --- a/jdk/test/java/nio/file/Path/CopyAndMove.java +++ b/jdk/test/java/nio/file/Path/CopyAndMove.java @@ -92,7 +92,6 @@ public class CopyAndMove { { assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly()); assertTrue(attrs1.isHidden() == attrs2.isHidden()); - assertTrue(attrs1.isArchive() == attrs2.isArchive()); assertTrue(attrs1.isSystem() == attrs2.isSystem()); } From b712d23c2f70257351319a9f051a89c08b853ee1 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Mon, 19 Oct 2009 20:01:45 +0100 Subject: [PATCH 080/172] 6879463: (file) DirectoryStream#iterator's remove method throws wrong exception when stream is closed Reviewed-by: sherman --- .../sun/nio/fs/UnixDirectoryStream.java | 3 ++- .../sun/nio/fs/WindowsDirectoryStream.java | 5 +++-- .../java/nio/file/DirectoryStream/Basic.java | 21 ++++++++++++++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java b/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java index 591f49051c2..79550d1bbde 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java +++ b/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java @@ -235,7 +235,8 @@ class UnixDirectoryStream @Override public void remove() { if (isClosed) { - throw new ClosedDirectoryStreamException(); + throwAsConcurrentModificationException(new + ClosedDirectoryStreamException()); } Path entry; synchronized (this) { diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java b/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java index df773489152..478648b0124 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java @@ -179,7 +179,7 @@ class WindowsDirectoryStream synchronized (closeLock) { if (!isOpen) throwAsConcurrentModificationException(new - IllegalStateException("Directory stream is closed")); + ClosedDirectoryStreamException()); try { name = FindNextFile(handle, findDataBuffer.address()); if (name == null) { @@ -236,7 +236,8 @@ class WindowsDirectoryStream @Override public void remove() { if (!isOpen) { - throw new IllegalStateException("Directory stream is closed"); + throwAsConcurrentModificationException(new + ClosedDirectoryStreamException()); } Path entry; synchronized (this) { diff --git a/jdk/test/java/nio/file/DirectoryStream/Basic.java b/jdk/test/java/nio/file/DirectoryStream/Basic.java index 4b5a5dff6be..87b5c38579d 100644 --- a/jdk/test/java/nio/file/DirectoryStream/Basic.java +++ b/jdk/test/java/nio/file/DirectoryStream/Basic.java @@ -154,8 +154,10 @@ public class Basic { stream.close(); // test IllegalStateException + dir.resolve(foo).createFile(); stream = dir.newDirectoryStream(); i = stream.iterator(); + i.next(); try { stream.iterator(); throw new RuntimeException("IllegalStateException not thrown as expected"); @@ -172,17 +174,26 @@ public class Basic { throw new RuntimeException("ConcurrentModificationException not thrown as expected"); } catch (ConcurrentModificationException x) { Throwable t = x.getCause(); - if (!(t instanceof IllegalStateException)) - throw new RuntimeException("Cause is not IllegalStateException as expected"); + if (!(t instanceof ClosedDirectoryStreamException)) + throw new RuntimeException("Cause is not ClosedDirectoryStreamException as expected"); } try { i.next(); - throw new RuntimeException("IllegalStateException not thrown as expected"); + throw new RuntimeException("ConcurrentModificationException not thrown as expected"); } catch (ConcurrentModificationException x) { Throwable t = x.getCause(); - if (!(t instanceof IllegalStateException)) - throw new RuntimeException("Cause is not IllegalStateException as expected"); + if (!(t instanceof ClosedDirectoryStreamException)) + throw new RuntimeException("Cause is not ClosedDirectoryStreamException as expected"); } + try { + i.remove(); + throw new RuntimeException("ConcurrentModificationException not thrown as expected"); + } catch (ConcurrentModificationException x) { + Throwable t = x.getCause(); + if (!(t instanceof ClosedDirectoryStreamException)) + throw new RuntimeException("Cause is not ClosedDirectoryStreamException as expected"); + } + } public static void main(String[] args) throws IOException { From 355021b7b0fa7edb9f0464eed970d041982bf9c1 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Mon, 19 Oct 2009 20:02:45 +0100 Subject: [PATCH 081/172] 6884480: (file) Path.relativize has typo in parameter description Reviewed-by: chegar --- jdk/src/share/classes/java/nio/file/Path.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/java/nio/file/Path.java b/jdk/src/share/classes/java/nio/file/Path.java index d9ba6de7835..8aa970c1364 100644 --- a/jdk/src/share/classes/java/nio/file/Path.java +++ b/jdk/src/share/classes/java/nio/file/Path.java @@ -412,7 +412,7 @@ public abstract class Path * dependent if {@code "a/b/../x"} would locate the same file as {@code "/a/x"}. * * @param other - * the resulting path + * the path to relativize against this path * * @return the resulting relative path, or {@code null} if both paths are * equal @@ -1615,23 +1615,23 @@ public abstract class Path * Tests if the file referenced by this object is the same file referenced * by another object. * - *

If this {@code FileRef} and the given {@code FileRef} are {@link + *

If this {@code Path} and the given {@code Path} are {@link * #equals(Object) equal} then this method returns {@code true} without checking - * if the file exists. If the {@code FileRef} and the given {@code FileRef} - * are associated with different providers, or the given {@code FileRef} is + * if the file exists. If the {@code Path} and the given {@code Path} + * are associated with different providers, or the given {@code Path} is * {@code null} then this method returns {@code false}. Otherwise, this method - * checks if both {@code FileRefs} locate the same file, and depending on the + * checks if both {@code Paths} locate the same file, and depending on the * implementation, may require to open or access both files. * *

If the file system and files remain static, then this method implements - * an equivalence relation for non-null {@code FileRefs}. + * an equivalence relation for non-null {@code Paths}. *