OpenJDK / bsd-port / jdk9 / jdk
changeset 13481:51e05d200a72
Merge
author | amurillo |
---|---|
date | Tue, 05 Jan 2016 13:08:05 -0800 |
parents | 2efa37c9e038 fb2a4d3c555b |
children | 05ce416aa7e0 af335ad593d6 |
files | src/java.base/share/classes/sun/invoke/anon/AnonymousClassLoader.java src/java.base/share/classes/sun/invoke/anon/ConstantPoolParser.java src/java.base/share/classes/sun/invoke/anon/ConstantPoolPatch.java src/java.base/share/classes/sun/invoke/anon/ConstantPoolVisitor.java src/java.base/share/classes/sun/invoke/anon/InvalidConstantPoolFormatException.java test/sun/invoke/anon/ConstantPoolPatch/OptimalMapSize.java |
diffstat | 22 files changed, 135 insertions(+), 1422 deletions(-) [+] |
line wrap: on
line diff
--- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Tue Jan 05 14:33:35 2016 -0500 +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Tue Jan 05 13:08:05 2016 -0800 @@ -39,6 +39,7 @@ import java.util.Collection; import java.util.Date; import java.util.concurrent.TimeUnit; +import jdk.internal.vm.annotation.ReservedStackAccess; /** * Provides a framework for implementing blocking locks and related @@ -886,6 +887,7 @@ * @param arg the acquire argument * @return {@code true} if interrupted while waiting */ + @ReservedStackAccess final boolean acquireQueued(final Node node, int arg) { try { boolean interrupted = false; @@ -1218,6 +1220,7 @@ * {@link #tryAcquire} but is otherwise uninterpreted and * can represent anything you like. */ + @ReservedStackAccess public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) @@ -1281,6 +1284,7 @@ * can represent anything you like. * @return the value returned from {@link #tryRelease} */ + @ReservedStackAccess public final boolean release(int arg) { if (tryRelease(arg)) { Node h = head; @@ -1361,6 +1365,7 @@ * and can represent anything you like. * @return the value returned from {@link #tryReleaseShared} */ + @ReservedStackAccess public final boolean releaseShared(int arg) { if (tryReleaseShared(arg)) { doReleaseShared();
--- a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java Tue Jan 05 14:33:35 2016 -0500 +++ b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java Tue Jan 05 13:08:05 2016 -0800 @@ -37,6 +37,7 @@ import java.util.Collection; import java.util.concurrent.TimeUnit; +import jdk.internal.vm.annotation.ReservedStackAccess; /** * A reentrant mutual exclusion {@link Lock} with the same basic @@ -127,6 +128,7 @@ * Performs non-fair tryLock. tryAcquire is implemented in * subclasses, but both need nonfair try for trylock method. */ + @ReservedStackAccess final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); @@ -146,6 +148,7 @@ return false; } + @ReservedStackAccess protected final boolean tryRelease(int releases) { int c = getState() - releases; if (Thread.currentThread() != getExclusiveOwnerThread()) @@ -203,6 +206,7 @@ * Performs lock. Try immediate barge, backing up to normal * acquire on failure. */ + @ReservedStackAccess final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); @@ -229,6 +233,7 @@ * Fair version of tryAcquire. Don't grant access unless * recursive call or no waiters or is first. */ + @ReservedStackAccess protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.base/share/classes/jdk/internal/vm/annotation/ReservedStackAccess.java Tue Jan 05 13:08:05 2016 -0800 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.vm.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * <p>An annotation expressing that a method is especially sensitive + * to stack overflows. This is a hint the JVM can use to grant access to + * extra stack space when executing this code if such feature is supported + * by the JVM. The JVM is free to ignore this annotation. + * + * A possible way for the JVM to improve the execution context for methods + * with this annotation is to reserve part of the thread's execution stack + * for them. Access to this section of the stack would be denied by default + * but could be granted if the JVM detects a possible stack overflow and + * the thread's call stack includes at least one annotated method. Even if + * access to this reserved area has been granted, the JVM might decide to + * throw a delayed StackOverflowError when the thread exits the annotated + * method. + * + * @since 1.9 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) +public @interface ReservedStackAccess { }
--- a/src/java.base/share/classes/sun/invoke/anon/AnonymousClassLoader.java Tue Jan 05 14:33:35 2016 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.invoke.anon; - -import java.io.EOFException; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * Anonymous class loader. Will load any valid classfile, producing - * a {@link Class} metaobject, without installing that class in the - * system dictionary. Therefore, {@link Class#forName(String)} will never - * produce a reference to an anonymous class. - * <p> - * The access permissions of the anonymous class are borrowed from - * a <em>host class</em>. The new class behaves as if it were an - * inner class of the host class. It can access the host's private - * members, if the creator of the class loader has permission to - * do so (or to create accessible reflective objects). - * <p> - * When the anonymous class is loaded, elements of its constant pool - * can be patched to new values. This provides a hook to pre-resolve - * named classes in the constant pool to other classes, including - * anonymous ones. Also, string constants can be pre-resolved to - * any reference. (The verifier treats non-string, non-class reference - * constants as plain objects.) - * <p> - * Why include the patching function? It makes some use cases much easier. - * Second, the constant pool needed some internal patching anyway, - * to anonymize the loaded class itself. Finally, if you are going - * to use this seriously, you'll want to build anonymous classes - * on top of pre-existing anonymous classes, and that requires patching. - * - * <p>%%% TO-DO: - * <ul> - * <li>needs better documentation</li> - * <li>needs more security work (for safe delegation)</li> - * <li>needs a clearer story about error processing</li> - * <li>patch member references also (use ';' as delimiter char)</li> - * <li>patch method references to (conforming) method handles</li> - * </ul> - * - * @author jrose - * @author Remi Forax - * @see <a href="http://blogs.sun.com/jrose/entry/anonymous_classes_in_the_vm"> - * http://blogs.sun.com/jrose/entry/anonymous_classes_in_the_vm</a> - */ - -public class AnonymousClassLoader { - final Class<?> hostClass; - - // Privileged constructor. - private AnonymousClassLoader(Class<?> hostClass) { - this.hostClass = hostClass; - } - - public static AnonymousClassLoader make(jdk.internal.misc.Unsafe unsafe, Class<?> hostClass) { - if (unsafe == null) throw new NullPointerException(); - return new AnonymousClassLoader(hostClass); - } - - public Class<?> loadClass(byte[] classFile) { - if (defineAnonymousClass == null) { - // no JVM support; try to fake an approximation - try { - return fakeLoadClass(new ConstantPoolParser(classFile).createPatch()); - } catch (InvalidConstantPoolFormatException ee) { - throw new IllegalArgumentException(ee); - } - } - return loadClass(classFile, null); - } - - public Class<?> loadClass(ConstantPoolPatch classPatch) { - if (defineAnonymousClass == null) { - // no JVM support; try to fake an approximation - return fakeLoadClass(classPatch); - } - Object[] patches = classPatch.patchArray; - // Convert class names (this late in the game) - // to use slash '/' instead of dot '.'. - // Java likes dots, but the JVM likes slashes. - for (int i = 0; i < patches.length; i++) { - Object value = patches[i]; - if (value != null) { - byte tag = classPatch.getTag(i); - switch (tag) { - case ConstantPoolVisitor.CONSTANT_Class: - if (value instanceof String) { - if (patches == classPatch.patchArray) - patches = patches.clone(); - patches[i] = ((String)value).replace('.', '/'); - } - break; - case ConstantPoolVisitor.CONSTANT_Fieldref: - case ConstantPoolVisitor.CONSTANT_Methodref: - case ConstantPoolVisitor.CONSTANT_InterfaceMethodref: - case ConstantPoolVisitor.CONSTANT_NameAndType: - // When/if the JVM supports these patches, - // we'll probably need to reformat them also. - // Meanwhile, let the class loader create the error. - break; - } - } - } - return loadClass(classPatch.outer.classFile, classPatch.patchArray); - } - - private Class<?> loadClass(byte[] classFile, Object[] patchArray) { - try { - return (Class<?>) - defineAnonymousClass.invoke(unsafe, - hostClass, classFile, patchArray); - } catch (Exception ex) { - throwReflectedException(ex); - throw new RuntimeException("error loading into "+hostClass, ex); - } - } - - private static void throwReflectedException(Exception ex) { - if (ex instanceof InvocationTargetException) { - Throwable tex = ((InvocationTargetException)ex).getTargetException(); - if (tex instanceof Error) - throw (Error) tex; - ex = (Exception) tex; - } - if (ex instanceof RuntimeException) { - throw (RuntimeException) ex; - } - } - - private Class<?> fakeLoadClass(ConstantPoolPatch classPatch) { - // Implementation: - // 1. Make up a new name nobody has used yet. - // 2. Inspect the tail-header of the class to find the this_class index. - // 3. Patch the CONSTANT_Class for this_class to the new name. - // 4. Add other CP entries required by (e.g.) string patches. - // 5. Flatten Class constants down to their names, making sure that - // the host class loader can pick them up again accurately. - // 6. Generate the edited class file bytes. - // - // Potential limitations: - // * The class won't be truly anonymous, and may interfere with others. - // * Flattened class constants might not work, because of loader issues. - // * Pseudo-string constants will not flatten down to real strings. - // * Method handles will (of course) fail to flatten to linkage strings. - if (true) throw new UnsupportedOperationException("NYI"); - Object[] cpArray; - try { - cpArray = classPatch.getOriginalCP(); - } catch (InvalidConstantPoolFormatException ex) { - throw new RuntimeException(ex); - } - int thisClassIndex = classPatch.getParser().getThisClassIndex(); - String thisClassName = (String) cpArray[thisClassIndex]; - synchronized (AnonymousClassLoader.class) { - thisClassName = thisClassName+"\\|"+(++fakeNameCounter); - } - classPatch.putUTF8(thisClassIndex, thisClassName); - byte[] classFile = null; - return unsafe.defineClass(null, classFile, 0, classFile.length, - hostClass.getClassLoader(), - hostClass.getProtectionDomain()); - } - private static int fakeNameCounter = 99999; - - // ignore two warnings on this line: - private static jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); - // preceding line requires that this class be on the boot class path - - private static final Method defineAnonymousClass; - static { - Method dac = null; - Class<? extends jdk.internal.misc.Unsafe> unsafeClass = unsafe.getClass(); - try { - dac = unsafeClass.getMethod("defineAnonymousClass", - Class.class, - byte[].class, - Object[].class); - } catch (Exception ee) { - dac = null; - } - defineAnonymousClass = dac; - } - - private static void noJVMSupport() { - throw new UnsupportedOperationException("no JVM support for anonymous classes"); - } - - - private static native Class<?> loadClassInternal(Class<?> hostClass, - byte[] classFile, - Object[] patchArray); - - public static byte[] readClassFile(Class<?> templateClass) throws IOException { - String templateName = templateClass.getName(); - int lastDot = templateName.lastIndexOf('.'); - java.net.URL url = templateClass.getResource(templateName.substring(lastDot+1)+".class"); - java.net.URLConnection connection = url.openConnection(); - int contentLength = connection.getContentLength(); - if (contentLength < 0) - throw new IOException("invalid content length "+contentLength); - - byte[] b = connection.getInputStream().readAllBytes(); - if (b.length != contentLength) - throw new EOFException("Expected:" + contentLength + ", read:" + b.length); - - return b; - } -}
--- a/src/java.base/share/classes/sun/invoke/anon/ConstantPoolParser.java Tue Jan 05 14:33:35 2016 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,368 +0,0 @@ -/* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.invoke.anon; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; - -import static sun.invoke.anon.ConstantPoolVisitor.*; - -/** A constant pool parser. - */ -public class ConstantPoolParser { - final byte[] classFile; - final byte[] tags; - final char[] firstHeader; // maghi, maglo, minor, major, cplen - - // these are filled in on first parse: - int endOffset; - char[] secondHeader; // flags, this_class, super_class, intlen - - // used to decode UTF8 array - private char[] charArray = new char[80]; - - /** Creates a constant pool parser. - * @param classFile an array of bytes containing a class. - * @throws InvalidConstantPoolFormatException if the header of the class has errors. - */ - public ConstantPoolParser(byte[] classFile) throws InvalidConstantPoolFormatException { - this.classFile = classFile; - this.firstHeader = parseHeader(classFile); - this.tags = new byte[firstHeader[4]]; - } - - /** Create a constant pool parser by loading the bytecodes of the - * class taken as argument. - * - * @param templateClass the class to parse. - * - * @throws IOException raised if an I/O occurs when loading - * the bytecode of the template class. - * @throws InvalidConstantPoolFormatException if the header of the class has errors. - * - * @see #ConstantPoolParser(byte[]) - * @see AnonymousClassLoader#readClassFile(Class) - */ - public ConstantPoolParser(Class<?> templateClass) throws IOException, InvalidConstantPoolFormatException { - this(AnonymousClassLoader.readClassFile(templateClass)); - } - - /** Creates an empty patch to patch the class file - * used by the current parser. - * @return a new class patch. - */ - public ConstantPoolPatch createPatch() { - return new ConstantPoolPatch(this); - } - - /** Report the tag of the indicated CP entry. - * @param index - * @return one of {@link ConstantPoolVisitor#CONSTANT_Utf8}, etc. - */ - public byte getTag(int index) { - getEndOffset(); // trigger an exception if we haven't parsed yet - return tags[index]; - } - - /** Report the length of the constant pool. */ - public int getLength() { - return firstHeader[4]; - } - - /** Report the offset, within the class file, of the start of the constant pool. */ - public int getStartOffset() { - return firstHeader.length * 2; - } - - /** Report the offset, within the class file, of the end of the constant pool. */ - public int getEndOffset() { - if (endOffset == 0) - throw new IllegalStateException("class file has not yet been parsed"); - return endOffset; - } - - /** Report the CP index of this class's own name. */ - public int getThisClassIndex() { - getEndOffset(); // provoke exception if not yet parsed - return secondHeader[1]; - } - - /** Report the total size of the class file. */ - public int getTailLength() { - return classFile.length - getEndOffset(); - } - - /** Write the head (header plus constant pool) - * of the class file to the indicated stream. - */ - public void writeHead(OutputStream out) throws IOException { - out.write(classFile, 0, getEndOffset()); - } - - /** Write the head (header plus constant pool) - * of the class file to the indicated stream, - * incorporating the non-null entries of the given array - * as patches. - */ - void writePatchedHead(OutputStream out, Object[] patchArray) { - // this will be useful to partially emulate the class loader on old JVMs - throw new UnsupportedOperationException("Not yet implemented"); - } - - /** Write the tail (everything after the constant pool) - * of the class file to the indicated stream. - */ - public void writeTail(OutputStream out) throws IOException { - out.write(classFile, getEndOffset(), getTailLength()); - } - - private static char[] parseHeader(byte[] classFile) throws InvalidConstantPoolFormatException { - char[] result = new char[5]; - ByteBuffer buffer = ByteBuffer.wrap(classFile); - for (int i = 0; i < result.length; i++) - result[i] = (char) getUnsignedShort(buffer); - int magic = result[0] << 16 | result[1] << 0; - if (magic != 0xCAFEBABE) - throw new InvalidConstantPoolFormatException("invalid magic number "+magic); - // skip major, minor version - int len = result[4]; - if (len < 1) - throw new InvalidConstantPoolFormatException("constant pool length < 1"); - return result; - } - - /** Parse the constant pool of the class - * calling a method visit* each time a constant pool entry is parsed. - * - * The order of the calls to visit* is not guaranteed to be the same - * than the order of the constant pool entry in the bytecode array. - * - * @param visitor - * @throws InvalidConstantPoolFormatException - */ - public void parse(ConstantPoolVisitor visitor) throws InvalidConstantPoolFormatException { - ByteBuffer buffer = ByteBuffer.wrap(classFile); - buffer.position(getStartOffset()); //skip header - - Object[] values = new Object[getLength()]; - try { - parseConstantPool(buffer, values, visitor); - } catch(BufferUnderflowException e) { - throw new InvalidConstantPoolFormatException(e); - } - if (endOffset == 0) { - endOffset = buffer.position(); - secondHeader = new char[4]; - for (int i = 0; i < secondHeader.length; i++) { - secondHeader[i] = (char) getUnsignedShort(buffer); - } - } - resolveConstantPool(values, visitor); - } - - private char[] getCharArray(int utfLength) { - if (utfLength <= charArray.length) - return charArray; - return charArray = new char[utfLength]; - } - - private void parseConstantPool(ByteBuffer buffer, Object[] values, ConstantPoolVisitor visitor) throws InvalidConstantPoolFormatException { - for (int i = 1; i < tags.length; ) { - byte tag = (byte) getUnsignedByte(buffer); - assert(tags[i] == 0 || tags[i] == tag); - tags[i] = tag; - switch (tag) { - case CONSTANT_Utf8: - int utfLen = getUnsignedShort(buffer); - String value = getUTF8(buffer, utfLen, getCharArray(utfLen)); - visitor.visitUTF8(i, CONSTANT_Utf8, value); - tags[i] = tag; - values[i++] = value; - break; - case CONSTANT_Integer: - visitor.visitConstantValue(i, tag, buffer.getInt()); - i++; - break; - case CONSTANT_Float: - visitor.visitConstantValue(i, tag, buffer.getFloat()); - i++; - break; - case CONSTANT_Long: - visitor.visitConstantValue(i, tag, buffer.getLong()); - i+=2; - break; - case CONSTANT_Double: - visitor.visitConstantValue(i, tag, buffer.getDouble()); - i+=2; - break; - - case CONSTANT_Class: // fall through: - case CONSTANT_String: - tags[i] = tag; - values[i++] = new int[] { getUnsignedShort(buffer) }; - break; - - case CONSTANT_Fieldref: // fall through: - case CONSTANT_Methodref: // fall through: - case CONSTANT_InterfaceMethodref: // fall through: - case CONSTANT_NameAndType: - tags[i] = tag; - values[i++] = new int[] { getUnsignedShort(buffer), getUnsignedShort(buffer) }; - break; - default: - throw new AssertionError("invalid constant "+tag); - } - } - } - - private void resolveConstantPool(Object[] values, ConstantPoolVisitor visitor) { - // clean out the int[] values, which are temporary - for (int beg = 1, end = values.length-1, beg2, end2; - beg <= end; - beg = beg2, end = end2) { - beg2 = end; end2 = beg-1; - //System.out.println("CP resolve pass: "+beg+".."+end); - for (int i = beg; i <= end; i++) { - Object value = values[i]; - if (!(value instanceof int[])) - continue; - int[] array = (int[]) value; - byte tag = tags[i]; - switch (tag) { - case CONSTANT_String: - String stringBody = (String) values[array[0]]; - visitor.visitConstantString(i, tag, stringBody, array[0]); - values[i] = null; - break; - case CONSTANT_Class: { - String className = (String) values[array[0]]; - // use the external form favored by Class.forName: - className = className.replace('/', '.'); - visitor.visitConstantString(i, tag, className, array[0]); - values[i] = className; - break; - } - case CONSTANT_NameAndType: { - String memberName = (String) values[array[0]]; - String signature = (String) values[array[1]]; - visitor.visitDescriptor(i, tag, memberName, signature, - array[0], array[1]); - values[i] = new String[] {memberName, signature}; - break; - } - case CONSTANT_Fieldref: // fall through: - case CONSTANT_Methodref: // fall through: - case CONSTANT_InterfaceMethodref: { - Object className = values[array[0]]; - Object nameAndType = values[array[1]]; - if (!(className instanceof String) || - !(nameAndType instanceof String[])) { - // one more pass is needed - if (beg2 > i) beg2 = i; - if (end2 < i) end2 = i; - continue; - } - String[] nameAndTypeArray = (String[]) nameAndType; - visitor.visitMemberRef(i, tag, - (String)className, - nameAndTypeArray[0], - nameAndTypeArray[1], - array[0], array[1]); - values[i] = null; - } - break; - default: - continue; - } - } - } - } - - private static int getUnsignedByte(ByteBuffer buffer) { - return buffer.get() & 0xFF; - } - - private static int getUnsignedShort(ByteBuffer buffer) { - int b1 = getUnsignedByte(buffer); - int b2 = getUnsignedByte(buffer); - return (b1 << 8) + (b2 << 0); - } - - private static String getUTF8(ByteBuffer buffer, int utfLen, char[] charArray) throws InvalidConstantPoolFormatException { - int utfLimit = buffer.position() + utfLen; - int index = 0; - while (buffer.position() < utfLimit) { - int c = buffer.get() & 0xff; - if (c > 127) { - buffer.position(buffer.position() - 1); - return getUTF8Extended(buffer, utfLimit, charArray, index); - } - charArray[index++] = (char)c; - } - return new String(charArray, 0, index); - } - - private static String getUTF8Extended(ByteBuffer buffer, int utfLimit, char[] charArray, int index) throws InvalidConstantPoolFormatException { - int c, c2, c3; - while (buffer.position() < utfLimit) { - c = buffer.get() & 0xff; - switch (c >> 4) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - /* 0xxxxxxx*/ - charArray[index++] = (char)c; - break; - case 12: case 13: - /* 110x xxxx 10xx xxxx*/ - c2 = buffer.get(); - if ((c2 & 0xC0) != 0x80) - throw new InvalidConstantPoolFormatException( - "malformed input around byte " + buffer.position()); - charArray[index++] = (char)(((c & 0x1F) << 6) | - (c2 & 0x3F)); - break; - case 14: - /* 1110 xxxx 10xx xxxx 10xx xxxx */ - c2 = buffer.get(); - c3 = buffer.get(); - if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) - throw new InvalidConstantPoolFormatException( - "malformed input around byte " + (buffer.position())); - charArray[index++] = (char)(((c & 0x0F) << 12) | - ((c2 & 0x3F) << 6) | - ((c3 & 0x3F) << 0)); - break; - default: - /* 10xx xxxx, 1111 xxxx */ - throw new InvalidConstantPoolFormatException( - "malformed input around byte " + buffer.position()); - } - } - // The number of chars produced may be less than utflen - return new String(charArray, 0, index); - } -}
--- a/src/java.base/share/classes/sun/invoke/anon/ConstantPoolPatch.java Tue Jan 05 14:33:35 2016 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,503 +0,0 @@ -/* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.invoke.anon; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Map; - -import static sun.invoke.anon.ConstantPoolVisitor.*; - -/** A class and its patched constant pool. - * - * This class allow to modify (patch) a constant pool - * by changing the value of its entry. - * Entry are referenced using index that can be get - * by parsing the constant pool using - * {@link ConstantPoolParser#parse(ConstantPoolVisitor)}. - * - * @see ConstantPoolVisitor - * @see ConstantPoolParser#createPatch() - */ -public class ConstantPoolPatch { - final ConstantPoolParser outer; - final Object[] patchArray; - - ConstantPoolPatch(ConstantPoolParser outer) { - this.outer = outer; - this.patchArray = new Object[outer.getLength()]; - } - - /** Create a {@link ConstantPoolParser} and - * a {@link ConstantPoolPatch} in one step. - * Equivalent to {@code new ConstantPoolParser(classFile).createPatch()}. - * - * @param classFile an array of bytes containing a class. - * @see #ConstantPoolParser(Class) - */ - public ConstantPoolPatch(byte[] classFile) throws InvalidConstantPoolFormatException { - this(new ConstantPoolParser(classFile)); - } - - /** Create a {@link ConstantPoolParser} and - * a {@link ConstantPoolPatch} in one step. - * Equivalent to {@code new ConstantPoolParser(templateClass).createPatch()}. - * - * @param templateClass the class to parse. - * @see #ConstantPoolParser(Class) - */ - public ConstantPoolPatch(Class<?> templateClass) throws IOException, InvalidConstantPoolFormatException { - this(new ConstantPoolParser(templateClass)); - } - - - /** Creates a patch from an existing patch. - * All changes are copied from that patch. - * @param patch a patch - * - * @see ConstantPoolParser#createPatch() - */ - public ConstantPoolPatch(ConstantPoolPatch patch) { - outer = patch.outer; - patchArray = patch.patchArray.clone(); - } - - /** Which parser built this patch? */ - public ConstantPoolParser getParser() { - return outer; - } - - /** Report the tag at the given index in the constant pool. */ - public byte getTag(int index) { - return outer.getTag(index); - } - - /** Report the current patch at the given index of the constant pool. - * Null means no patch will be made. - * To observe the unpatched entry at the given index, use - * {@link #getParser()}{@code .}@link ConstantPoolParser#parse(ConstantPoolVisitor)} - */ - public Object getPatch(int index) { - Object value = patchArray[index]; - if (value == null) return null; - switch (getTag(index)) { - case CONSTANT_Fieldref: - case CONSTANT_Methodref: - case CONSTANT_InterfaceMethodref: - if (value instanceof String) - value = stripSemis(2, (String) value); - break; - case CONSTANT_NameAndType: - if (value instanceof String) - value = stripSemis(1, (String) value); - break; - } - return value; - } - - /** Clear all patches. */ - public void clear() { - Arrays.fill(patchArray, null); - } - - /** Clear one patch. */ - public void clear(int index) { - patchArray[index] = null; - } - - /** Produce the patches as an array. */ - public Object[] getPatches() { - return patchArray.clone(); - } - - /** Produce the original constant pool as an array. */ - public Object[] getOriginalCP() throws InvalidConstantPoolFormatException { - return getOriginalCP(0, patchArray.length, -1); - } - - /** Walk the constant pool, applying patches using the given map. - * - * @param utf8Map Utf8 strings to modify, if encountered - * @param classMap Classes (or their names) to modify, if encountered - * @param valueMap Constant values to modify, if encountered - * @param deleteUsedEntries if true, delete map entries that are used - */ - public void putPatches(final Map<String,String> utf8Map, - final Map<String,Object> classMap, - final Map<Object,Object> valueMap, - boolean deleteUsedEntries) throws InvalidConstantPoolFormatException { - final HashSet<String> usedUtf8Keys; - final HashSet<String> usedClassKeys; - final HashSet<Object> usedValueKeys; - if (deleteUsedEntries) { - usedUtf8Keys = (utf8Map == null) ? null : new HashSet<String>(); - usedClassKeys = (classMap == null) ? null : new HashSet<String>(); - usedValueKeys = (valueMap == null) ? null : new HashSet<Object>(); - } else { - usedUtf8Keys = null; - usedClassKeys = null; - usedValueKeys = null; - } - - outer.parse(new ConstantPoolVisitor() { - - @Override - public void visitUTF8(int index, byte tag, String utf8) { - putUTF8(index, utf8Map.get(utf8)); - if (usedUtf8Keys != null) usedUtf8Keys.add(utf8); - } - - @Override - public void visitConstantValue(int index, byte tag, Object value) { - putConstantValue(index, tag, valueMap.get(value)); - if (usedValueKeys != null) usedValueKeys.add(value); - } - - @Override - public void visitConstantString(int index, byte tag, String name, int nameIndex) { - if (tag == CONSTANT_Class) { - putConstantValue(index, tag, classMap.get(name)); - if (usedClassKeys != null) usedClassKeys.add(name); - } else { - assert(tag == CONSTANT_String); - visitConstantValue(index, tag, name); - } - } - }); - if (usedUtf8Keys != null) utf8Map.keySet().removeAll(usedUtf8Keys); - if (usedClassKeys != null) classMap.keySet().removeAll(usedClassKeys); - if (usedValueKeys != null) valueMap.keySet().removeAll(usedValueKeys); - } - - Object[] getOriginalCP(final int startIndex, - final int endIndex, - final int tagMask) throws InvalidConstantPoolFormatException { - final Object[] cpArray = new Object[endIndex - startIndex]; - outer.parse(new ConstantPoolVisitor() { - - void show(int index, byte tag, Object value) { - if (index < startIndex || index >= endIndex) return; - if (((1 << tag) & tagMask) == 0) return; - cpArray[index - startIndex] = value; - } - - @Override - public void visitUTF8(int index, byte tag, String utf8) { - show(index, tag, utf8); - } - - @Override - public void visitConstantValue(int index, byte tag, Object value) { - assert(tag != CONSTANT_String); - show(index, tag, value); - } - - @Override - public void visitConstantString(int index, byte tag, - String value, int j) { - show(index, tag, value); - } - - @Override - public void visitMemberRef(int index, byte tag, - String className, String memberName, - String signature, - int j, int k) { - show(index, tag, new String[]{ className, memberName, signature }); - } - - @Override - public void visitDescriptor(int index, byte tag, - String memberName, String signature, - int j, int k) { - show(index, tag, new String[]{ memberName, signature }); - } - }); - return cpArray; - } - - /** Write the head (header plus constant pool) - * of the patched class file to the indicated stream. - */ - void writeHead(OutputStream out) throws IOException { - outer.writePatchedHead(out, patchArray); - } - - /** Write the tail (everything after the constant pool) - * of the patched class file to the indicated stream. - */ - void writeTail(OutputStream out) throws IOException { - outer.writeTail(out); - } - - private void checkConstantTag(byte tag, Object value) { - if (value == null) - throw new IllegalArgumentException( - "invalid null constant value"); - if (classForTag(tag) != value.getClass()) - throw new IllegalArgumentException( - "invalid constant value" - + (tag == CONSTANT_None ? "" - : " for tag "+tagName(tag)) - + " of class "+value.getClass()); - } - - private void checkTag(int index, byte putTag) { - byte tag = outer.tags[index]; - if (tag != putTag) - throw new IllegalArgumentException( - "invalid put operation" - + " for " + tagName(putTag) - + " at index " + index + " found " + tagName(tag)); - } - - private void checkTagMask(int index, int tagBitMask) { - byte tag = outer.tags[index]; - int tagBit = ((tag & 0x1F) == tag) ? (1 << tag) : 0; - if ((tagBit & tagBitMask) == 0) - throw new IllegalArgumentException( - "invalid put operation" - + " at index " + index + " found " + tagName(tag)); - } - - private static void checkMemberName(String memberName) { - if (memberName.indexOf(';') >= 0) - throw new IllegalArgumentException("memberName " + memberName + " contains a ';'"); - } - - /** Set the entry of the constant pool indexed by index to - * a new string. - * - * @param index an index to a constant pool entry containing a - * {@link ConstantPoolVisitor#CONSTANT_Utf8} value. - * @param utf8 a string - * - * @see ConstantPoolVisitor#visitUTF8(int, byte, String) - */ - public void putUTF8(int index, String utf8) { - if (utf8 == null) { clear(index); return; } - checkTag(index, CONSTANT_Utf8); - patchArray[index] = utf8; - } - - /** Set the entry of the constant pool indexed by index to - * a new value, depending on its dynamic type. - * - * @param index an index to a constant pool entry containing a - * one of the following structures: - * {@link ConstantPoolVisitor#CONSTANT_Integer}, - * {@link ConstantPoolVisitor#CONSTANT_Float}, - * {@link ConstantPoolVisitor#CONSTANT_Long}, - * {@link ConstantPoolVisitor#CONSTANT_Double}, - * {@link ConstantPoolVisitor#CONSTANT_String}, or - * {@link ConstantPoolVisitor#CONSTANT_Class} - * @param value a boxed int, float, long or double; or a string or class object - * @throws IllegalArgumentException if the type of the constant does not - * match the constant pool entry type, - * as reported by {@link #getTag(int)} - * - * @see #putConstantValue(int, byte, Object) - * @see ConstantPoolVisitor#visitConstantValue(int, byte, Object) - * @see ConstantPoolVisitor#visitConstantString(int, byte, String, int) - */ - public void putConstantValue(int index, Object value) { - if (value == null) { clear(index); return; } - byte tag = tagForConstant(value.getClass()); - checkConstantTag(tag, value); - checkTag(index, tag); - patchArray[index] = value; - } - - /** Set the entry of the constant pool indexed by index to - * a new value. - * - * @param index an index to a constant pool entry matching the given tag - * @param tag one of the following values: - * {@link ConstantPoolVisitor#CONSTANT_Integer}, - * {@link ConstantPoolVisitor#CONSTANT_Float}, - * {@link ConstantPoolVisitor#CONSTANT_Long}, - * {@link ConstantPoolVisitor#CONSTANT_Double}, - * {@link ConstantPoolVisitor#CONSTANT_String}, or - * {@link ConstantPoolVisitor#CONSTANT_Class} - * @param value a boxed number, string, or class object - * @throws IllegalArgumentException if the type of the constant does not - * match the constant pool entry type, or if a class name contains - * '/' or ';' - * - * @see #putConstantValue(int, Object) - * @see ConstantPoolVisitor#visitConstantValue(int, byte, Object) - * @see ConstantPoolVisitor#visitConstantString(int, byte, String, int) - */ - public void putConstantValue(int index, byte tag, Object value) { - if (value == null) { clear(index); return; } - checkTag(index, tag); - if (tag == CONSTANT_Class && value instanceof String) { - checkClassName((String) value); - } else if (tag == CONSTANT_String) { - // the JVM accepts any object as a patch for a string - } else { - // make sure the incoming value is the right type - checkConstantTag(tag, value); - } - checkTag(index, tag); - patchArray[index] = value; - } - - /** Set the entry of the constant pool indexed by index to - * a new {@link ConstantPoolVisitor#CONSTANT_NameAndType} value. - * - * @param index an index to a constant pool entry containing a - * {@link ConstantPoolVisitor#CONSTANT_NameAndType} value. - * @param memberName a memberName - * @param signature a signature - * @throws IllegalArgumentException if memberName contains the character ';' - * - * @see ConstantPoolVisitor#visitDescriptor(int, byte, String, String, int, int) - */ - public void putDescriptor(int index, String memberName, String signature) { - checkTag(index, CONSTANT_NameAndType); - checkMemberName(memberName); - patchArray[index] = addSemis(memberName, signature); - } - - /** Set the entry of the constant pool indexed by index to - * a new {@link ConstantPoolVisitor#CONSTANT_Fieldref}, - * {@link ConstantPoolVisitor#CONSTANT_Methodref}, or - * {@link ConstantPoolVisitor#CONSTANT_InterfaceMethodref} value. - * - * @param index an index to a constant pool entry containing a member reference - * @param className a class name - * @param memberName a field or method name - * @param signature a field or method signature - * @throws IllegalArgumentException if memberName contains the character ';' - * or signature is not a correct signature - * - * @see ConstantPoolVisitor#visitMemberRef(int, byte, String, String, String, int, int) - */ - public void putMemberRef(int index, byte tag, - String className, String memberName, String signature) { - checkTagMask(tag, CONSTANT_MemberRef_MASK); - checkTag(index, tag); - checkClassName(className); - checkMemberName(memberName); - if (signature.startsWith("(") == (tag == CONSTANT_Fieldref)) - throw new IllegalArgumentException("bad signature: "+signature); - patchArray[index] = addSemis(className, memberName, signature); - } - - private static final int CONSTANT_MemberRef_MASK = - CONSTANT_Fieldref - | CONSTANT_Methodref - | CONSTANT_InterfaceMethodref; - - private static final Map<Class<?>, Byte> CONSTANT_VALUE_CLASS_TAG - = new IdentityHashMap<Class<?>, Byte>(6); - private static final Class<?>[] CONSTANT_VALUE_CLASS = new Class<?>[16]; - static { - Object[][] values = { - {Integer.class, CONSTANT_Integer}, - {Long.class, CONSTANT_Long}, - {Float.class, CONSTANT_Float}, - {Double.class, CONSTANT_Double}, - {String.class, CONSTANT_String}, - {Class.class, CONSTANT_Class} - }; - for (Object[] value : values) { - Class<?> cls = (Class<?>)value[0]; - Byte tag = (Byte) value[1]; - CONSTANT_VALUE_CLASS_TAG.put(cls, tag); - CONSTANT_VALUE_CLASS[(byte)tag] = cls; - } - } - - static Class<?> classForTag(byte tag) { - if ((tag & 0xFF) >= CONSTANT_VALUE_CLASS.length) - return null; - return CONSTANT_VALUE_CLASS[tag]; - } - - static byte tagForConstant(Class<?> cls) { - Byte tag = CONSTANT_VALUE_CLASS_TAG.get(cls); - return (tag == null) ? CONSTANT_None : (byte)tag; - } - - private static void checkClassName(String className) { - if (className.indexOf('/') >= 0 || className.indexOf(';') >= 0) - throw new IllegalArgumentException("invalid class name " + className); - } - - static String addSemis(String name, String... names) { - StringBuilder buf = new StringBuilder(name.length() * 5); - buf.append(name); - for (String name2 : names) { - buf.append(';').append(name2); - } - String res = buf.toString(); - assert(stripSemis(names.length, res)[0].equals(name)); - assert(stripSemis(names.length, res)[1].equals(names[0])); - assert(names.length == 1 || - stripSemis(names.length, res)[2].equals(names[1])); - return res; - } - - static String[] stripSemis(int count, String string) { - String[] res = new String[count+1]; - int pos = 0; - for (int i = 0; i < count; i++) { - int pos2 = string.indexOf(';', pos); - if (pos2 < 0) pos2 = string.length(); // yuck - res[i] = string.substring(pos, pos2); - pos = pos2; - } - res[count] = string.substring(pos); - return res; - } - - public String toString() { - StringBuilder buf = new StringBuilder(this.getClass().getName()); - buf.append("{"); - Object[] origCP = null; - for (int i = 0; i < patchArray.length; i++) { - if (patchArray[i] == null) continue; - if (origCP != null) { - buf.append(", "); - } else { - try { - origCP = getOriginalCP(); - } catch (InvalidConstantPoolFormatException ee) { - origCP = new Object[0]; - } - } - Object orig = (i < origCP.length) ? origCP[i] : "?"; - buf.append(orig).append("=").append(patchArray[i]); - } - buf.append("}"); - return buf.toString(); - } -}
--- a/src/java.base/share/classes/sun/invoke/anon/ConstantPoolVisitor.java Tue Jan 05 14:33:35 2016 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.invoke.anon; - -/** - * A visitor called by {@link ConstantPoolParser#parse(ConstantPoolVisitor)} - * when a constant pool entry is parsed. - * <p> - * A visit* method is called when a constant pool entry is parsed. - * The first argument is always the constant pool index. - * The second argument is always the constant pool tag, - * even for methods like {@link #visitUTF8(int, byte, String)} which only apply to one tag. - * String arguments refer to Utf8 or NameAndType entries declared elsewhere, - * and are always accompanied by the indexes of those entries. - * <p> - * The order of the calls to the visit* methods is not necessarily related - * to the order of the entries in the constant pool. - * If one entry has a reference to another entry, the latter (lower-level) - * entry will be visited first. - * <p> - * The following table shows the relation between constant pool entry - * types and the corresponding visit* methods: - * - * <table border=1 cellpadding=5 summary="constant pool visitor methods"> - * <tr><th>Tag(s)</th><th>Method</th></tr> - * <tr> - * <td>{@link #CONSTANT_Utf8}</td> - * <td>{@link #visitUTF8(int, byte, String)}</td> - * </tr><tr> - * <td>{@link #CONSTANT_Integer}, {@link #CONSTANT_Float}, - * {@link #CONSTANT_Long}, {@link #CONSTANT_Double}</td> - * <td>{@link #visitConstantValue(int, byte, Object)}</td> - * </tr><tr> - * <td>{@link #CONSTANT_String}, {@link #CONSTANT_Class}</td> - * <td>{@link #visitConstantString(int, byte, String, int)}</td> - * </tr><tr> - * <td>{@link #CONSTANT_NameAndType}</td> - * <td>{@link #visitDescriptor(int, byte, String, String, int, int)}</td> - * </tr><tr> - * <td>{@link #CONSTANT_Fieldref}, - * {@link #CONSTANT_Methodref}, - * {@link #CONSTANT_InterfaceMethodref}</td> - * <td>{@link #visitMemberRef(int, byte, String, String, String, int, int)}</td> - * </tr> - * </table> - * - * @see ConstantPoolPatch - * @author Remi Forax - * @author jrose - */ -public class ConstantPoolVisitor { - /** Called each time an UTF8 constant pool entry is found. - * @param index the constant pool index - * @param tag always {@link #CONSTANT_Utf8} - * @param utf8 string encoded in modified UTF-8 format passed as a {@code String} - * - * @see ConstantPoolPatch#putUTF8(int, String) - */ - public void visitUTF8(int index, byte tag, String utf8) { - // do nothing - } - - /** Called for each constant pool entry that encodes an integer, - * a float, a long, or a double. - * Constant strings and classes are not managed by this method but - * by {@link #visitConstantString(int, byte, String, int)}. - * - * @param index the constant pool index - * @param tag one of {@link #CONSTANT_Integer}, - * {@link #CONSTANT_Float}, - * {@link #CONSTANT_Long}, - * or {@link #CONSTANT_Double} - * @param value encoded value - * - * @see ConstantPoolPatch#putConstantValue(int, Object) - */ - public void visitConstantValue(int index, byte tag, Object value) { - // do nothing - } - - /** Called for each constant pool entry that encodes a string or a class. - * @param index the constant pool index - * @param tag one of {@link #CONSTANT_String}, - * {@link #CONSTANT_Class}, - * @param name string body or class name (using dot separator) - * @param nameIndex the index of the Utf8 string for the name - * - * @see ConstantPoolPatch#putConstantValue(int, byte, Object) - */ - public void visitConstantString(int index, byte tag, - String name, int nameIndex) { - // do nothing - } - - /** Called for each constant pool entry that encodes a name and type. - * @param index the constant pool index - * @param tag always {@link #CONSTANT_NameAndType} - * @param memberName a field or method name - * @param signature the member signature - * @param memberNameIndex index of the Utf8 string for the member name - * @param signatureIndex index of the Utf8 string for the signature - * - * @see ConstantPoolPatch#putDescriptor(int, String, String) - */ - public void visitDescriptor(int index, byte tag, - String memberName, String signature, - int memberNameIndex, int signatureIndex) { - // do nothing - } - - /** Called for each constant pool entry that encodes a field or method. - * @param index the constant pool index - * @param tag one of {@link #CONSTANT_Fieldref}, - * or {@link #CONSTANT_Methodref}, - * or {@link #CONSTANT_InterfaceMethodref} - * @param className the class name (using dot separator) - * @param memberName name of the field or method - * @param signature the field or method signature - * @param classNameIndex index of the Utf8 string for the class name - * @param descriptorIndex index of the NameAndType descriptor constant - * - * @see ConstantPoolPatch#putMemberRef(int, byte, String, String, String) - */ - public void visitMemberRef(int index, byte tag, - String className, String memberName, String signature, - int classNameIndex, int descriptorIndex) { - // do nothing - } - - public static final byte - CONSTANT_None = 0, - CONSTANT_Utf8 = 1, - //CONSTANT_Unicode = 2, /* unused */ - CONSTANT_Integer = 3, - CONSTANT_Float = 4, - CONSTANT_Long = 5, - CONSTANT_Double = 6, - CONSTANT_Class = 7, - CONSTANT_String = 8, - CONSTANT_Fieldref = 9, - CONSTANT_Methodref = 10, - CONSTANT_InterfaceMethodref = 11, - CONSTANT_NameAndType = 12; - - private static String[] TAG_NAMES = { - "Empty", - "Utf8", - null, //"Unicode", - "Integer", - "Float", - "Long", - "Double", - "Class", - "String", - "Fieldref", - "Methodref", - "InterfaceMethodref", - "NameAndType" - }; - - public static String tagName(byte tag) { - String name = null; - if ((tag & 0xFF) < TAG_NAMES.length) - name = TAG_NAMES[tag]; - if (name == null) - name = "Unknown#"+(tag&0xFF); - return name; - } -}
--- a/src/java.base/share/classes/sun/invoke/anon/InvalidConstantPoolFormatException.java Tue Jan 05 14:33:35 2016 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.invoke.anon; - -/** Exception used when there is an error in the constant pool - * format. - */ -public class InvalidConstantPoolFormatException extends Exception { - private static final long serialVersionUID=-6103888330523770949L; - - public InvalidConstantPoolFormatException(String message,Throwable cause) { - super(message,cause); - } - - public InvalidConstantPoolFormatException(String message) { - super(message); - } - - public InvalidConstantPoolFormatException(Throwable cause) { - super(cause); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.base/unix/conf/ppc64le/jvm.cfg Tue Jan 05 13:08:05 2016 -0800 @@ -0,0 +1,34 @@ +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# 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=<jvm_dir>" option, but that too is unsupported +# and may not be available in a future release. +# +-server KNOWN +-client IGNORE
--- a/test/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java Tue Jan 05 14:33:35 2016 -0500 +++ b/test/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java Tue Jan 05 13:08:05 2016 -0800 @@ -62,7 +62,7 @@ ProcessBuilder pb = ProcessTools. createJavaProcessBuilder( "-XX:+UseConcMarkSweepGC", // this will cause UseParNewGC to be FLAG_SET_ERGO - "-XX:+PrintGCDetails", + "-XX:+UseCodeAging", "-XX:+UseCerealGC", // Should be ignored. "-XX:Flags=" + flagsFile.getAbsolutePath(), "-cp", System.getProperty("test.class.path"), @@ -97,7 +97,7 @@ // Not set, so should be default checkOrigin("ManagementServer", Origin.DEFAULT); // Set on the command line - checkOrigin("PrintGCDetails", Origin.VM_CREATION); + checkOrigin("UseCodeAging", Origin.VM_CREATION); // Set in _JAVA_OPTIONS checkOrigin("TraceExceptions", Origin.ENVIRON_VAR); // Set in JAVA_TOOL_OPTIONS
--- a/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java Tue Jan 05 14:33:35 2016 -0500 +++ b/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java Tue Jan 05 13:08:05 2016 -0800 @@ -28,7 +28,7 @@ * @author Mandy Chung * * @modules jdk.management - * @run main/othervm -XX:+PrintGCDetails GetVMOption + * @run main/othervm -XX:+HeapDumpOnOutOfMemoryError GetVMOption */ import com.sun.management.HotSpotDiagnosticMXBean; @@ -38,7 +38,7 @@ import javax.management.MBeanServer; public class GetVMOption { - private static final String PRINT_GC_DETAILS = "PrintGCDetails"; + private static final String HEAP_DUMP_ON_OOM = "HeapDumpOnOutOfMemoryError"; private static final String EXPECTED_VALUE = "true"; private static final String BAD_OPTION = "BadOption"; private static final String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME = @@ -58,7 +58,7 @@ } private static void checkVMOption(HotSpotDiagnosticMXBean mbean) { - VMOption option = mbean.getVMOption(PRINT_GC_DETAILS); + VMOption option = mbean.getVMOption(HEAP_DUMP_ON_OOM); if (!option.getValue().equalsIgnoreCase(EXPECTED_VALUE)) { throw new RuntimeException("Unexpected value: " + option.getValue() + " expected: " + EXPECTED_VALUE);
--- a/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java Tue Jan 05 14:33:35 2016 -0500 +++ b/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java Tue Jan 05 13:08:05 2016 -0800 @@ -30,7 +30,7 @@ * @author Jaroslav Bachorik * * @modules jdk.management - * @run main/othervm -XX:+PrintGCDetails SetVMOption + * @run main/othervm -XX:+HeapDumpOnOutOfMemoryError SetVMOption */ import java.lang.management.ManagementFactory; @@ -40,7 +40,7 @@ import com.sun.management.VMOption.Origin; public class SetVMOption { - private static final String PRINT_GC_DETAILS = "PrintGCDetails"; + private static final String HEAP_DUMP_ON_OOM = "HeapDumpOnOutOfMemoryError"; private static final String EXPECTED_VALUE = "true"; private static final String BAD_VALUE = "yes"; private static final String NEW_VALUE = "false"; @@ -51,7 +51,7 @@ mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); - VMOption option = findPrintGCDetailsOption(); + VMOption option = findHeapDumpOnOomOption(); if (!option.getValue().equalsIgnoreCase(EXPECTED_VALUE)) { throw new RuntimeException("Unexpected value: " + option.getValue() + " expected: " + EXPECTED_VALUE); @@ -61,14 +61,14 @@ option.getOrigin() + " expected: VM_CREATION"); } if (!option.isWriteable()) { - throw new RuntimeException("Expected " + PRINT_GC_DETAILS + + throw new RuntimeException("Expected " + HEAP_DUMP_ON_OOM + " to be writeable"); } // set VM option to a new value - mbean.setVMOption(PRINT_GC_DETAILS, NEW_VALUE); + mbean.setVMOption(HEAP_DUMP_ON_OOM, NEW_VALUE); - option = findPrintGCDetailsOption(); + option = findHeapDumpOnOomOption(); if (!option.getValue().equalsIgnoreCase(NEW_VALUE)) { throw new RuntimeException("Unexpected value: " + option.getValue() + " expected: " + NEW_VALUE); @@ -77,7 +77,7 @@ throw new RuntimeException("Unexpected origin: " + option.getOrigin() + " expected: MANAGEMENT"); } - VMOption o = mbean.getVMOption(PRINT_GC_DETAILS); + VMOption o = mbean.getVMOption(HEAP_DUMP_ON_OOM); if (!option.getValue().equals(o.getValue())) { throw new RuntimeException("Unmatched value: " + option.getValue() + " expected: " + o.getValue()); @@ -123,17 +123,17 @@ } } - public static VMOption findPrintGCDetailsOption() { + public static VMOption findHeapDumpOnOomOption() { List<VMOption> options = mbean.getDiagnosticOptions(); VMOption gcDetails = null; for (VMOption o : options) { - if (o.getName().equals(PRINT_GC_DETAILS)) { + if (o.getName().equals(HEAP_DUMP_ON_OOM)) { gcDetails = o; break; } } if (gcDetails == null) { - throw new RuntimeException("VM option " + PRINT_GC_DETAILS + + throw new RuntimeException("VM option " + HEAP_DUMP_ON_OOM + " not found"); } return gcDetails;
--- a/test/java/lang/management/MemoryMXBean/LowMemoryTest.java Tue Jan 05 14:33:35 2016 -0500 +++ b/test/java/lang/management/MemoryMXBean/LowMemoryTest.java Tue Jan 05 13:08:05 2016 -0800 @@ -100,7 +100,7 @@ opts.addAll(Arrays.asList(Utils.getTestJavaOpts())); opts.add("-cp"); opts.add(System.getProperty("test.class.path", "test.class.path")); - opts.add("-XX:+PrintGCDetails"); + opts.add("-Xlog:gc*=debug"); opts.addAll(Arrays.asList(testOpts)); opts.add(classMain);
--- a/test/java/lang/management/MemoryMXBean/RunUtil.java Tue Jan 05 14:33:35 2016 -0500 +++ b/test/java/lang/management/MemoryMXBean/RunUtil.java Tue Jan 05 13:08:05 2016 -0800 @@ -66,7 +66,7 @@ opts.addAll(Arrays.asList(Utils.getTestJavaOpts())); opts.add("-cp"); opts.add(System.getProperty("test.class.path", "test.class.path")); - opts.add("-XX:+PrintGCDetails"); + opts.add("-Xlog:gc*=debug"); if (clearGcOpts) { opts = Utils.removeGcOpts(opts);
--- a/test/java/lang/management/RuntimeMXBean/TestInputArgument.sh Tue Jan 05 14:33:35 2016 -0500 +++ b/test/java/lang/management/RuntimeMXBean/TestInputArgument.sh Tue Jan 05 13:08:05 2016 -0800 @@ -48,8 +48,8 @@ runOne InputArgument -runOne -XX:+UseFastJNIAccessors -XX:+PrintGCDetails InputArgument -XX:+PrintGCDetails -runOne -XX:+UseFastJNIAccessors -XX:+PrintGCDetails InputArgument -XX:+UseFastJNIAccessors +runOne -XX:+UseFastJNIAccessors -Xlog:gc*=debug InputArgument +runOne -XX:+UseFastJNIAccessors -Xlog:gc*=debug InputArgument -XX:+UseFastJNIAccessors runOne "-Dprops=one two three" InputArgument "-Dprops=one two three" exit 0
--- a/test/java/text/Format/DecimalFormat/FormatMicroBenchmark.java Tue Jan 05 14:33:35 2016 -0500 +++ b/test/java/text/Format/DecimalFormat/FormatMicroBenchmark.java Tue Jan 05 13:08:05 2016 -0800 @@ -51,7 +51,7 @@ * getting reliable numbers. Otherwise GC activity may corrupt results. * As of jdk80b48 using "-Xms500m -Xmx500m -XX:NewSize=400m" covers * all cases. - * - Optionally using "-XX:+printGC" option provides information that + * - Optionally using "-Xlog:gc" option provides information that * helps checking any GC activity while benches are run. * * Vm Options: @@ -60,7 +60,7 @@ * non fast-path case: -Xms500m -Xmx500m -XX:NewSize=400m * or use worst case (non fast-path above) with both types of algorithm. * - * - use -XX:+PrintGC to verify memory consumption of the benchmarks. + * - use -Xlog:gc to verify memory consumption of the benchmarks. * (See "Checking Memory Consumption" below). * * Description: @@ -166,7 +166,7 @@ * but is not enough, since any unexpected incremental GC may lower * artificially the estimation of the memory consumption. * - * Options to set are -Xms, -Xmx, -XX:NewSize, plus -XX:+PrintGC to evaluate + * Options to set are -Xms, -Xmx, -XX:NewSize, plus -Xlog:gc to evaluate * correctly the values of these options. When running "-verbose", varying * numbers reported for memory consumption may indicate bad choices for these * options. @@ -217,7 +217,7 @@ " getting reliable numbers. Otherwise GC activity may corrupt results.\n" + " As of jdk80b48 using \"-Xms500m -Xmx500m -XX:NewSize=400m\" covers \n" + " all cases.\n" + - " - Optionally using \"-XX:+printGC\" option provides information that \n" + + " - Optionally using \"-Xlog:gc\" option provides information that \n" + " helps checking any GC activity while benches are run.\n\n" + "Look at the heading comments and description in source code for " + "detailed information.\n");
--- a/test/lib/testlibrary/jdk/testlibrary/JDKToolLauncher.java Tue Jan 05 14:33:35 2016 -0500 +++ b/test/lib/testlibrary/jdk/testlibrary/JDKToolLauncher.java Tue Jan 05 13:08:05 2016 -0800 @@ -38,8 +38,7 @@ * <pre> * {@code * JDKToolLauncher jmap = JDKToolLauncher.create("jmap") - * .addVMArg("-XX:+PrintGC"); - * .addVMArg("-XX:+PrintGCDetails") + * .addVMArg("-Xlog:gc*=debug") * .addToolArg("-heap") * .addToolArg(pid); * ProcessBuilder pb = new ProcessBuilder(jmap.getCommand());
--- a/test/sun/invoke/anon/ConstantPoolPatch/OptimalMapSize.java Tue Jan 05 14:33:35 2016 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @test - * @bug 8080535 - * @summary Static storages should be initialized with optimal capacity - * @library /lib/testlibrary - * @build jdk.testlibrary.OptimalCapacity - * @run main OptimalMapSize - */ - -import jdk.testlibrary.OptimalCapacity; - -public class OptimalMapSize { - public static void main(String[] args) throws Throwable { - OptimalCapacity.ofIdentityHashMap( - Class.forName("sun.invoke.anon.ConstantPoolPatch"), - "CONSTANT_VALUE_CLASS_TAG", 6); - } -}
--- a/test/sun/security/pkcs11/PKCS11Test.java Tue Jan 05 14:33:35 2016 -0500 +++ b/test/sun/security/pkcs11/PKCS11Test.java Tue Jan 05 13:08:05 2016 -0800 @@ -540,6 +540,7 @@ "/usr/lib/x86_64-linux-gnu/", "/usr/lib/x86_64-linux-gnu/nss/", "/usr/lib64/"}); osMap.put("Linux-ppc64-64", new String[]{"/usr/lib64/"}); + osMap.put("Linux-ppc64le-64", new String[]{"/usr/lib64/"}); osMap.put("Windows-x86-32", new String[]{ PKCS11_BASE + "/nss/lib/windows-i586/".replace('/', SEP)}); osMap.put("Windows-amd64-64", new String[]{
--- a/test/sun/tools/jinfo/JInfoRunningProcessFlagTest.java Tue Jan 05 14:33:35 2016 -0500 +++ b/test/sun/tools/jinfo/JInfoRunningProcessFlagTest.java Tue Jan 05 13:08:05 2016 -0800 @@ -60,30 +60,30 @@ } private static void testFlagPlus() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfo("-flag", "+PrintGC"); + OutputAnalyzer output = JInfoHelper.jinfo("-flag", "+HeapDumpOnOutOfMemoryError"); output.shouldHaveExitValue(0); - output = JInfoHelper.jinfo("-flag", "PrintGC"); + output = JInfoHelper.jinfo("-flag", "HeapDumpOnOutOfMemoryError"); output.shouldHaveExitValue(0); - output.shouldContain("+PrintGC"); - verifyIsEnabled("PrintGC"); + output.shouldContain("+HeapDumpOnOutOfMemoryError"); + verifyIsEnabled("HeapDumpOnOutOfMemoryError"); } private static void testFlagMinus() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfo("-flag", "-PrintGC"); + OutputAnalyzer output = JInfoHelper.jinfo("-flag", "-HeapDumpOnOutOfMemoryError"); output.shouldHaveExitValue(0); - output = JInfoHelper.jinfo("-flag", "PrintGC"); + output = JInfoHelper.jinfo("-flag", "HeapDumpOnOutOfMemoryError"); output.shouldHaveExitValue(0); - output.shouldContain("-PrintGC"); - verifyIsDisabled("PrintGC"); + output.shouldContain("-HeapDumpOnOutOfMemoryError"); + verifyIsDisabled("HeapDumpOnOutOfMemoryError"); } private static void testFlagEqual() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfo("-flag", "PrintGC=1"); + OutputAnalyzer output = JInfoHelper.jinfo("-flag", "HeapDumpOnOutOfMemoryError=1"); output.shouldHaveExitValue(0); - output = JInfoHelper.jinfo("-flag", "PrintGC"); + output = JInfoHelper.jinfo("-flag", "HeapDumpOnOutOfMemoryError"); output.shouldHaveExitValue(0); - output.shouldContain("+PrintGC"); - verifyIsEnabled("PrintGC"); + output.shouldContain("+HeapDumpOnOutOfMemoryError"); + verifyIsEnabled("HeapDumpOnOutOfMemoryError"); } private static void testInvalidFlag() throws Exception {
--- a/test/sun/tools/jps/JpsHelper.java Tue Jan 05 14:33:35 2016 -0500 +++ b/test/sun/tools/jps/JpsHelper.java Tue Jan 05 13:08:05 2016 -0800 @@ -98,7 +98,7 @@ * -XX:+UsePerfData is required for running the tests on embedded platforms. */ public static final String[] VM_ARGS = { - "-XX:+UsePerfData", "-Xmx512m", "-XX:+PrintGCDetails", + "-XX:+UsePerfData", "-Xmx512m", "-Xlog:gc", "-Dmultiline.prop=value1\nvalue2\r\nvalue3" }; /**
--- a/test/tools/launcher/Settings.java Tue Jan 05 14:33:35 2016 -0500 +++ b/test/tools/launcher/Settings.java Tue Jan 05 13:08:05 2016 -0800 @@ -74,7 +74,7 @@ static void runTestOptionDefault() throws IOException { String stackSize = "256"; // in kb - if (getArch().equals("ppc64")) { + if (getArch().equals("ppc64") || getArch().equals("ppc64le")) { stackSize = "800"; } TestResult tr = null;