anonk: move source files to JDK
authorjrose
Thu Jan 29 14:18:20 2009 -0800 (9 months ago)
changeset 32df387891ff76
parent 31232a5bd9f4f8
child 33f7d1fffbe8eb
anonk: move source files to JDK
anonk.proj.patch
--- a/anonk.proj.patch Tue Jan 27 19:16:06 2009 -0800
+++ b/anonk.proj.patch Thu Jan 29 14:18:20 2009 -0800
@@ -76,7 +76,7 @@ new file mode 100644
new file mode 100644
--- /dev/null
+++ b/src/share/projects/anonk/nbproject/project.properties
-@@ -0,0 +1,63 @@
+@@ -0,0 +1,65 @@
+application.title=AnonymousClass
+application.vendor=jrose
+build.classes.dir=${build.dir}/classes
@@ -138,13 +138,15 @@ new file mode 100644
+# One or both refs probably need fixing:
+file.reference.projects=${env.HOME}/Projects
+file.reference.davinci.sources.jdk=${file.reference.projects}/davinci/sources/jdk
-+src.src.dir=src
++src.src.dir=${file.reference.davinci.sources.jdk}/src/share/classes
++src.src2.dir=src
+test.src.dir=test
++davinci.patch.name=anonk
diff --git a/src/share/projects/anonk/nbproject/project.xml b/src/share/projects/anonk/nbproject/project.xml
new file mode 100644
--- /dev/null
+++ b/src/share/projects/anonk/nbproject/project.xml
-@@ -0,0 +1,16 @@
+@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.java.j2seproject</type>
@@ -152,8 +154,10 @@ new file mode 100644
+ <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
+ <name>AnonymousClass</name>
+ <minimum-ant-version>1.6.5</minimum-ant-version>
++ <explicit-platform explicit-source-supported="true"/>
+ <source-roots>
-+ <root id="src.src.dir" name="Source Packages"/>
++ <root id="src.src.dir" name="JDK Source Packages"/>
++ <root id="src.src2.dir" name="Local Sources"/>
+ </source-roots>
+ <test-roots>
+ <root id="test.src.dir"/>
@@ -161,2779 +165,6 @@ new file mode 100644
+ </data>
+ </configuration>
+</project>
-diff --git a/src/share/projects/anonk/src/java/dyn/AnonymousClassLoader.java b/src/share/projects/anonk/src/java/dyn/AnonymousClassLoader.java
-new file mode 100644
---- /dev/null
-+++ b/src/share/projects/anonk/src/java/dyn/AnonymousClassLoader.java
-@@ -0,0 +1,297 @@
-+/*
-+ * Copyright 2008 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.dyn;
-+
-+import java.io.IOException;
-+import java.io.InputStream;
-+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;
-+
-+ // Note: Do not refactor the calls to checkHostClass unless you
-+ // also adjust this constant:
-+ private static int CHC_CALLERS = 3;
-+
-+ public AnonymousClassLoader() {
-+ this.hostClass = checkHostClass(null);
-+ }
-+ public AnonymousClassLoader(Class<?> hostClass) {
-+ this.hostClass = checkHostClass(hostClass);
-+ }
-+
-+ private static Class<?> getTopLevelClass(Class<?> clazz) {
-+ for(Class<?> outer = clazz.getDeclaringClass(); outer != null;
-+ outer = outer.getDeclaringClass()) {
-+ clazz = outer;
-+ }
-+ return clazz;
-+ }
-+
-+ private static Class<?> checkHostClass(Class<?> hostClass) {
-+ // called only from the constructor
-+ // does a context-sensitive check on caller class
-+ // CC[0..3] = {Reflection, this.checkHostClass, this.<init>, caller}
-+ Class<?> caller = sun.reflect.Reflection.getCallerClass(CHC_CALLERS);
-+
-+ if (caller == null) {
-+ // called from the JVM directly
-+ if (hostClass == null)
-+ return AnonymousClassLoader.class; // anything central will do
-+ return hostClass;
-+ }
-+
-+ if (hostClass == null)
-+ hostClass = caller; // default value is caller itself
-+
-+ // anonymous class will access hostClass on behalf of caller
-+ Class<?> callee = hostClass;
-+
-+ if (caller == callee)
-+ // caller can always nominate itself to grant caller's own access rights
-+ return hostClass;
-+
-+ // normalize caller and callee to their top-level classes:
-+ caller = getTopLevelClass(caller);
-+ callee = getTopLevelClass(callee);
-+ if (caller == callee)
-+ return caller;
-+
-+ ClassLoader callerCL = caller.getClassLoader();
-+ if (callerCL == null) {
-+ // caller is trusted code, so accept the proposed hostClass
-+ return hostClass;
-+ }
-+
-+ // %%% should do something with doPrivileged, because trusted
-+ // code should have a way to execute on behalf of
-+ // partially-trusted clients
-+
-+ // Does the caller have the right to access the private
-+ // members of the callee? If not, raise an error.
-+ final int ACC_PRIVATE = 2;
-+ try {
-+ sun.reflect.Reflection.ensureMemberAccess(caller, callee, null, ACC_PRIVATE);
-+ } catch (IllegalAccessException ee) {
-+ throw new IllegalArgumentException(ee);
-+ }
-+
-+ return 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:
-+ static sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
-+ // preceding line requires that this class be on the boot class path
-+
-+ static private final Method defineAnonymousClass;
-+ static {
-+ Method dac = null;
-+ Class<? extends sun.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[] 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;
-+ }
-+}
-diff --git a/src/share/projects/anonk/src/java/dyn/ConstantPoolParser.java b/src/share/projects/anonk/src/java/dyn/ConstantPoolParser.java
-new file mode 100644
---- /dev/null
-+++ b/src/share/projects/anonk/src/java/dyn/ConstantPoolParser.java
-@@ -0,0 +1,368 @@
-+/*
-+ * Copyright 2008 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.dyn;
-+
-+import java.io.IOException;
-+import java.io.OutputStream;
-+import java.nio.BufferUnderflowException;
-+import java.nio.ByteBuffer;
-+
-+import static java.dyn.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);
-+ }
-+}
-diff --git a/src/share/projects/anonk/src/java/dyn/ConstantPoolPatch.java b/src/share/projects/anonk/src/java/dyn/ConstantPoolPatch.java
-new file mode 100644
---- /dev/null
-+++ b/src/share/projects/anonk/src/java/dyn/ConstantPoolPatch.java
-@@ -0,0 +1,503 @@
-+/*
-+ * Copyright 2008 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.dyn;
-+
-+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 java.dyn.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);
-+ }
-+
-+ static private 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>();
-+ 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();
-+ }
-+}
-diff --git a/src/share/projects/anonk/src/java/dyn/ConstantPoolVisitor.java b/src/share/projects/anonk/src/java/dyn/ConstantPoolVisitor.java
-new file mode 100644
---- /dev/null
-+++ b/src/share/projects/anonk/src/java/dyn/ConstantPoolVisitor.java
-@@ -0,0 +1,192 @@
-+/*
-+ * Copyright 2008 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.dyn;
-+
-+/**
-+ * 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;
-+ }
-+}
-diff --git a/src/share/projects/anonk/src/java/dyn/InvalidConstantPoolFormatException.java b/src/share/projects/anonk/src/java/dyn/InvalidConstantPoolFormatException.java
-new file mode 100644
---- /dev/null
-+++ b/src/share/projects/anonk/src/java/dyn/InvalidConstantPoolFormatException.java
-@@ -0,0 +1,45 @@
-+/*
-+ * Copyright 2008 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.dyn;
-+
-+/** 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);
-+ }
-+}
-diff --git a/src/share/projects/anonk/src/sun/misc/Unsafe.java b/src/share/projects/anonk/src/sun/misc/Unsafe.java
-new file mode 100644
---- /dev/null
-+++ b/src/share/projects/anonk/src/sun/misc/Unsafe.java
-@@ -0,0 +1,1008 @@
-+/*
-+ * Copyright 2000-2008 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.misc;
-+
-+import java.security.*;
-+import java.lang.reflect.*;
-+
-+
-+/**
-+ * A collection of methods for performing low-level, unsafe operations.
-+ * Although the class and all methods are public, use of this class is
-+ * limited because only trusted code can obtain instances of it.
-+ *
-+ * @author John R. Rose
-+ * @see #getUnsafe
-+ */
-+
-+public final class Unsafe {
-+
-+ private static native void registerNatives();
-+ static {
-+ registerNatives();
-+ try {
-+ Class ref = Class.forName("sun.reflect.Reflection");
-+ java.lang.reflect.Method rmtf = ref.getDeclaredMethod("registerMethodsToFilter", Class.class, String.class);
-+ rmtf.invoke(Unsafe.class, "getUnsafe");
-+ } catch (Exception ex) {
-+ }
-+ }
-+
-+ private Unsafe() {}
-+
-+ private static final Unsafe theUnsafe = new Unsafe();
-+
-+ /**
-+ * Provides the caller with the capability of performing unsafe
-+ * operations.
-+ *
-+ * <p> The returned <code>Unsafe</code> object should be carefully guarded
-+ * by the caller, since it can be used to read and write data at arbitrary
-+ * memory addresses. It must never be passed to untrusted code.
-+ *
-+ * <p> Most methods in this class are very low-level, and correspond to a
-+ * small number of hardware instructions (on typical machines). Compilers
-+ * are encouraged to optimize these methods accordingly.
-+ *
-+ * <p> Here is a suggested idiom for using unsafe operations:
-+ *
-+ * <blockquote><pre>
-+ * class MyTrustedClass {
-+ * private static final Unsafe unsafe = Unsafe.getUnsafe();
-+ * ...
-+ * private long myCountAddress = ...;
-+ * public int getCount() { return unsafe.getByte(myCountAddress); }
-+ * }
-+ * </pre></blockquote>
-+ *
-+ * (It may assist compilers to make the local variable be
-+ * <code>final</code>.)
-+ *
-+ * @exception SecurityException if a security manager exists and its
-+ * <code>checkPropertiesAccess</code> method doesn't allow
-+ * access to the system properties.
-+ */
-+ public static Unsafe getUnsafe() {
-+ Class cc = sun.reflect.Reflection.getCallerClass(2);
-+ if (cc.getClassLoader() != null)
-+ throw new SecurityException("Unsafe");
-+ return theUnsafe;
-+ }
-+
-+ /// peek and poke operations
-+ /// (compilers should optimize these to memory ops)
-+
-+ // These work on object fields in the Java heap.
-+ // They will not work on elements of packed arrays.
-+
-+ /**
-+ * Fetches a value from a given Java variable.
-+ * More specifically, fetches a field or array element within the given
-+ * object <code>o</code> at the given offset, or (if <code>o</code> is
-+ * null) from the memory address whose numerical value is the given
-+ * offset.
-+ * <p>
-+ * The results are undefined unless one of the following cases is true:
-+ * <ul>
-+ * <li>The offset was obtained from {@link #objectFieldOffset} on
-+ * the {@link java.lang.reflect.Field} of some Java field and the object
-+ * referred to by <code>o</code> is of a class compatible with that
-+ * field's class.
-+ *
-+ * <li>The offset and object reference <code>o</code> (either null or
-+ * non-null) were both obtained via {@link #staticFieldOffset}
-+ * and {@link #staticFieldBase} (respectively) from the
-+ * reflective {@link Field} representation of some Java field.
-+ *
-+ * <li>The object referred to by <code>o</code> is an array, and the offset
-+ * is an integer of the form <code>B+N*S</code>, where <code>N</code> is
-+ * a valid index into the array, and <code>B</code> and <code>S</code> are
-+ * the values obtained by {@link #arrayBaseOffset} and {@link
-+ * #arrayIndexScale} (respectively) from the array's class. The value
-+ * referred to is the <code>N</code><em>th</em> element of the array.
-+ *
-+ * </ul>
-+ * <p>
-+ * If one of the above cases is true, the call references a specific Java
-+ * variable (field or array element). However, the results are undefined
-+ * if that variable is not in fact of the type returned by this method.
-+ * <p>
-+ * This method refers to a variable by means of two parameters, and so
-+ * it provides (in effect) a <em>double-register</em> addressing mode
-+ * for Java variables. When the object reference is null, this method
-+ * uses its offset as an absolute address. This is similar in operation
-+ * to methods such as {@link #getInt(long)}, which provide (in effect) a
-+ * <em>single-register</em> addressing mode for non-Java variables.
-+ * However, because Java variables may have a different layout in memory
-+ * from non-Java variables, programmers should not assume that these
-+ * two addressing modes are ever equivalent. Also, programmers should
-+ * remember that offsets from the double-register addressing mode cannot
-+ * be portably confused with longs used in the single-register addressing
-+ * mode.
-+ *
-+ * @param o Java heap object in which the variable resides, if any, else
-+ * null
-+ * @param offset indication of where the variable resides in a Java heap
-+ * object, if any, else a memory address locating the variable
-+ * statically
-+ * @return the value fetched from the indicated Java variable
-+ * @throws RuntimeException No defined exceptions are thrown, not even
-+ * {@link NullPointerException}
-+ */
-+ public native int getInt(Object o, long offset);
-+
-+ /**
-+ * Stores a value into a given Java variable.
-+ * <p>
-+ * The first two parameters are interpreted exactly as with
-+ * {@link #getInt(Object, long)} to refer to a specific
-+ * Java variable (field or array element). The given value
-+ * is stored into that variable.
-+ * <p>
-+ * The variable must be of the same type as the method
-+ * parameter <code>x</code>.
-+ *
-+ * @param o Java heap object in which the variable resides, if any, else
-+ * null
-+ * @param offset indication of where the variable resides in a Java heap
-+ * object, if any, else a memory address locating the variable
-+ * statically
-+ * @param x the value to store into the indicated Java variable
-+ * @throws RuntimeException No defined exceptions are thrown, not even
-+ * {@link NullPointerException}
-+ */
-+ public native void putInt(Object o, long offset, int x);
-+
-+ /**
-+ * Fetches a reference value from a given Java variable.
-+ * @see #getInt(Object, long)
-+ */
-+ public native Object getObject(Object o, long offset);
-+
-+ /**
-+ * Stores a reference value into a given Java variable.
-+ * <p>
-+ * Unless the reference <code>x</code> being stored is either null
-+ * or matches the field type, the results are undefined.
-+ * If the reference <code>o</code> is non-null, car marks or
-+ * other store barriers for that object (if the VM requires them)
-+ * are updated.
-+ * @see #putInt(Object, int, int)
-+ */
-+ public native void putObject(Object o, long offset, Object x);
-+
-+ /** @see #getInt(Object, long) */
-+ public native boolean getBoolean(Object o, long offset);
-+ /** @see #putInt(Object, int, int) */
-+ public native void putBoolean(Object o, long offset, boolean x);
-+ /** @see #getInt(Object, long) */
-+ public native byte getByte(Object o, long offset);
-+ /** @see #putInt(Object, int, int) */
-+ public native void putByte(Object o, long offset, byte x);
-+ /** @see #getInt(Object, long) */
-+ public native short getShort(Object o, long offset);
-+ /** @see #putInt(Object, int, int) */
-+ public native void putShort(Object o, long offset, short x);
-+ /** @see #getInt(Object, long) */
-+ public native char getChar(Object o, long offset);
-+ /** @see #putInt(Object, int, int) */
-+ public native void putChar(Object o, long offset, char x);
-+ /** @see #getInt(Object, long) */
-+ public native long getLong(Object o, long offset);
-+ /** @see #putInt(Object, int, int) */
-+ public native void putLong(Object o, long offset, long x);
-+ /** @see #getInt(Object, long) */
-+ public native float getFloat(Object o, long offset);
-+ /** @see #putInt(Object, int, int) */
-+ public native void putFloat(Object o, long offset, float x);
-+ /** @see #getInt(Object, long) */
-+ public native double getDouble(Object o, long offset);
-+ /** @see #putInt(Object, int, int) */
-+ public native void putDouble(Object o, long offset, double x);
-+
-+ /**
-+ * This method, like all others with 32-bit offsets, was native
-+ * in a previous release but is now a wrapper which simply casts
-+ * the offset to a long value. It provides backward compatibility
-+ * with bytecodes compiled against 1.4.
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public int getInt(Object o, int offset) {
-+ return getInt(o, (long)offset);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public void putInt(Object o, int offset, int x) {
-+ putInt(o, (long)offset, x);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public Object getObject(Object o, int offset) {
-+ return getObject(o, (long)offset);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public void putObject(Object o, int offset, Object x) {
-+ putObject(o, (long)offset, x);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public boolean getBoolean(Object o, int offset) {
-+ return getBoolean(o, (long)offset);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public void putBoolean(Object o, int offset, boolean x) {
-+ putBoolean(o, (long)offset, x);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public byte getByte(Object o, int offset) {
-+ return getByte(o, (long)offset);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public void putByte(Object o, int offset, byte x) {
-+ putByte(o, (long)offset, x);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public short getShort(Object o, int offset) {
-+ return getShort(o, (long)offset);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public void putShort(Object o, int offset, short x) {
-+ putShort(o, (long)offset, x);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public char getChar(Object o, int offset) {
-+ return getChar(o, (long)offset);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public void putChar(Object o, int offset, char x) {
-+ putChar(o, (long)offset, x);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public long getLong(Object o, int offset) {
-+ return getLong(o, (long)offset);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public void putLong(Object o, int offset, long x) {
-+ putLong(o, (long)offset, x);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public float getFloat(Object o, int offset) {
-+ return getFloat(o, (long)offset);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public void putFloat(Object o, int offset, float x) {
-+ putFloat(o, (long)offset, x);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public double getDouble(Object o, int offset) {
-+ return getDouble(o, (long)offset);
-+ }
-+
-+ /**
-+ * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-+ * See {@link #staticFieldOffset}.
-+ */
-+ @Deprecated
-+ public void putDouble(Object o, int offset, double x) {
-+ putDouble(o, (long)offset, x);
-+ }
-+
-+ // These work on values in the C heap.
-+
-+ /**
-+ * Fetches a value from a given memory address. If the address is zero, or
-+ * does not point into a block obtained from {@link #allocateMemory}, the
-+ * results are undefined.
-+ *
-+ * @see #allocateMemory
-+ */
-+ public native byte getByte(long address);
-+
-+ /**
-+ * Stores a value into a given memory address. If the address is zero, or
-+ * does not point into a block obtained from {@link #allocateMemory}, the
-+ * results are undefined.
-+ *
-+ * @see #getByte(long)
-+ */
-+ public native void putByte(long address, byte x);
-+
-+ /** @see #getByte(long) */
-+ public native short getShort(long address);
-+ /** @see #putByte(long, byte) */
-+ public native void putShort(long address, short x);
-+ /** @see #getByte(long) */
-+ public native char getChar(long address);
-+ /** @see #putByte(long, byte) */
-+ public native void putChar(long address, char x);
-+ /** @see #getByte(long) */
-+ public native int getInt(long address);
-+ /** @see #putByte(long, byte) */
-+ public native void putInt(long address, int x);
-+ /** @see #getByte(long) */
-+ public native long getLong(long address);
-+ /** @see #putByte(long, byte) */
-+ public native void putLong(long address, long x);
-+ /** @see #getByte(long) */
-+ public native float getFloat(long address);
-+ /** @see #putByte(long, byte) */
-+ public native void putFloat(long address, float x);
-+ /** @see #getByte(long) */
-+ public native double getDouble(long address);
-+ /** @see #putByte(long, byte) */
-+ public native void putDouble(long address, double x);
-+
-+ /**
-+ * Fetches a native pointer from a given memory address. If the address is
-+ * zero, or does not point into a block obtained from {@link
-+ * #allocateMemory}, the results are undefined.
-+ *
-+ * <p> If the native pointer is less than 64 bits wide, it is extended as
-+ * an unsigned number to a Java long. The pointer may be indexed by any
-+ * given byte offset, simply by adding that offset (as a simple integer) to
-+ * the long representing the pointer. The number of bytes actually read
-+ * from the target address maybe determined by consulting {@link
-+ * #addressSize}.
-+ *
-+ * @see #allocateMemory
-+ */
-+ public native long getAddress(long address);
-+
-+ /**
-+ * Stores a native pointer into a given memory address. If the address is
-+ * zero, or does not point into a block obtained from {@link
-+ * #allocateMemory}, the results are undefined.
-+ *
-+ * <p> The number of bytes actually written at the target address maybe
-+ * determined by consulting {@link #addressSize}.
-+ *
-+ * @see #getAddress(long)
-+ */
-+ public native void putAddress(long address, long x);
-+
-+ /// wrappers for malloc, realloc, free:
-+
-+ /**
-+ * Allocates a new block of native memory, of the given size in bytes. The
-+ * contents of the memory are uninitialized; they will generally be
-+ * garbage. The resulting native pointer will never be zero, and will be
-+ * aligned for all value types. Dispose of this memory by calling {@link
-+ * #freeMemory}, or resize it with {@link #reallocateMemory}.
-+ *
-+ * @throws IllegalArgumentException if the size is negative or too large
-+ * for the native size_t type
-+ *
-+ * @throws OutOfMemoryError if the allocation is refused by the system
-+ *
-+ * @see #getByte(long)
-+ * @see #putByte(long, byte)
-+ */
-+ public native long allocateMemory(long bytes);
-+
-+ /**
-+ * Resizes a new block of native memory, to the given size in bytes. The
-+ * contents of the new block past the size of the old block are
-+ * uninitialized; they will generally be garbage. The resulting native
-+ * pointer will be zero if and only if the requested size is zero. The
-+ * resulting native pointer will be aligned for all value types. Dispose
-+ * of this memory by calling {@link #freeMemory}, or resize it with {@link
-+ * #reallocateMemory}. The address passed to this method may be null, in
-+ * which case an allocation will be performed.
-+ *
-+ * @throws IllegalArgumentException if the size is negative or too large
-+ * for the native size_t type
-+ *
-+ * @throws OutOfMemoryError if the allocation is refused by the system
-+ *
-+ * @see #allocateMemory
-+ */
-+ public native long reallocateMemory(long address, long bytes);
-+
-+ /**
-+ * Sets all bytes in a given block of memory to a fixed value
-+ * (usually zero).
-+ *
-+ * <p>This method determines a block's base address by means of two parameters,
-+ * and so it provides (in effect) a <em>double-register</em> addressing mode,
-+ * as discussed in {@link #getInt(Object,long)}. When the object reference is null,
-+ * the offset supplies an absolute base address.
-+ *
-+ * <p>The stores are in coherent (atomic) units of a size determined
-+ * by the address and length parameters. If the effective address and
-+ * length are all even modulo 8, the stores take place in 'long' units.
-+ * If the effective address and length are (resp.) even modulo 4 or 2,
-+ * the stores take place in units of 'int' or 'short'.
-+ *
-+ * @since 1.7
-+ */
-+ public native void setMemory(Object o, long offset, long bytes, byte value);
-+
-+ /**
-+ * Sets all bytes in a given block of memory to a fixed value
-+ * (usually zero). This provides a <em>single-register</em> addressing mode,
-+ * as discussed in {@link #getInt(Object,long)}.
-+ *
-+ * <p>Equivalent to <code>setMemory(null, address, bytes, value)</code>.
-+ */
-+ public void setMemory(long address, long bytes, byte value) {
-+ setMemory(null, address, bytes, value);
-+ }
-+
-+ /**
-+ * Sets all bytes in a given block of memory to a copy of another
-+ * block.
-+ *
-+ * <p>This method determines each block's base address by means of two parameters,
-+ * and so it provides (in effect) a <em>double-register</em> addressing mode,
-+ * as discussed in {@link #getInt(Object,long)}. When the object reference is null,
-+ * the offset supplies an absolute base address.
-+ *
-+ * <p>The transfers are in coherent (atomic) units of a size determined
-+ * by the address and length parameters. If the effective addresses and
-+ * length are all even modulo 8, the transfer takes place in 'long' units.
-+ * If the effective addresses and length are (resp.) even modulo 4 or 2,
-+ * the transfer takes place in units of 'int' or 'short'.
-+ *
-+ * @since 1.7
-+ */
-+ public native void copyMemory(Object srcBase, long srcOffset,
-+ Object destBase, long destOffset,
-+ long bytes);
-+ /**
-+ * Sets all bytes in a given block of memory to a copy of another
-+ * block. This provides a <em>single-register</em> addressing mode,
-+ * as discussed in {@link #getInt(Object,long)}.
-+ *
-+ * Equivalent to <code>copyMemory(null, srcAddress, null, destAddress, bytes)</code>.
-+ */
-+ public void copyMemory(long srcAddress, long destAddress, long bytes) {
-+ copyMemory(null, srcAddress, null, destAddress, bytes);
-+ }
-+
-+ /**
-+ * Disposes of a block of native memory, as obtained from {@link
-+ * #allocateMemory} or {@link #reallocateMemory}. The address passed to
-+ * this method may be null, in which case no action is taken.
-+ *
-+ * @see #allocateMemory
-+ */
-+ public native void freeMemory(long address);
-+
-+ /// random queries
-+
-+ /**
-+ * This constant differs from all results that will ever be returned from
-+ * {@link #staticFieldOffset}, {@link #objectFieldOffset},
-+ * or {@link #arrayBaseOffset}.
-+ */
-+ public static final int INVALID_FIELD_OFFSET = -1;
-+
-+ /**
-+ * Returns the offset of a field, truncated to 32 bits.
-+ * This method is implemented as follows:
-+ * <blockquote><pre>
-+ * public int fieldOffset(Field f) {
-+ * if (Modifier.isStatic(f.getModifiers()))
-+ * return (int) staticFieldOffset(f);
-+ * else
-+ * return (int) objectFieldOffset(f);
-+ * }
-+ * </pre></blockquote>
-+ * @deprecated As of 1.4.1, use {@link #staticFieldOffset} for static
-+ * fields and {@link #objectFieldOffset} for non-static fields.
-+ */
-+ @Deprecated
-+ public int fieldOffset(Field f) {
-+ if (Modifier.isStatic(f.getModifiers()))
-+ return (int) staticFieldOffset(f);
-+ else
-+ return (int) objectFieldOffset(f);
-+ }
-+
-+ /**
-+ * Returns the base address for accessing some static field
-+ * in the given class. This method is implemented as follows:
-+ * <blockquote><pre>
-+ * public Object staticFieldBase(Class c) {
-+ * Field[] fields = c.getDeclaredFields();
-+ * for (int i = 0; i < fields.length; i++) {
-+ * if (Modifier.isStatic(fields[i].getModifiers())) {
-+ * return staticFieldBase(fields[i]);
-+ * }
-+ * }
-+ * return null;
-+ * }
-+ * </pre></blockquote>
-+ * @deprecated As of 1.4.1, use {@link #staticFieldBase(Field)}
-+ * to obtain the base pertaining to a specific {@link Field}.
-+ * This method works only for JVMs which store all statics
-+ * for a given class in one place.
-+ */
-+ @Deprecated
-+ public Object staticFieldBase(Class c) {
-+ Field[] fields = c.getDeclaredFields();
-+ for (int i = 0; i < fields.length; i++) {
-+ if (Modifier.isStatic(fields[i].getModifiers())) {
-+ return staticFieldBase(fields[i]);
-+ }
-+ }
-+ return null;
-+ }
-+
-+ /**
-+ * Report the location of a given field in the storage allocation of its
-+ * class. Do not expect to perform any sort of arithmetic on this offset;
-+ * it is just a cookie which is passed to the unsafe heap memory accessors.
-+ *
-+ * <p>Any given field will always have the same offset and base, and no
-+ * two distinct fields of the same class will ever have the same offset
-+ * and base.
-+ *
-+ * <p>As of 1.4.1, offsets for fields are represented as long values,
-+ * although the Sun JVM does not use the most significant 32 bits.
-+ * However, JVM implementations which store static fields at absolute
-+ * addresses can use long offsets and null base pointers to express
-+ * the field locations in a form usable by {@link #getInt(Object,long)}.
-+ * Therefore, code which will be ported to such JVMs on 64-bit platforms
-+ * must preserve all bits of static field offsets.
-+ * @see #getInt(Object, long)
-+ */
-+ public native long staticFieldOffset(Field f);
-+
-+ /**
-+ * Report the location of a given static field, in conjunction with {@link
-+ * #staticFieldBase}.
-+ * <p>Do not expect to perform any sort of arithmetic on this offset;
-+ * it is just a cookie which is passed to the unsafe heap memory accessors.
-+ *
-+ * <p>Any given field will always have the same offset, and no two distinct
-+ * fields of the same class will ever have the same offset.
-+ *
-+ * <p>As of 1.4.1, offsets for fields are represented as long values,
-+ * although the Sun JVM does not use the most significant 32 bits.
-+ * It is hard to imagine a JVM technology which needs more than
-+ * a few bits to encode an offset within a non-array object,
-+ * However, for consistency with other methods in this class,
-+ * this method reports its result as a long value.
-+ * @see #getInt(Object, long)
-+ */
-+ public native long objectFieldOffset(Field f);
-+
-+ /**
-+ * Report the location of a given static field, in conjunction with {@link
-+ * #staticFieldOffset}.
-+ * <p>Fetch the base "Object", if any, with which static fields of the
-+ * given class can be accessed via methods like {@link #getInt(Object,
-+ * long)}. This value may be null. This value may refer to an object
-+ * which is a "cookie", not guaranteed to be a real Object, and it should
-+ * not be used in any way except as argument to the get and put routines in
-+ * this class.
-+ */
-+ public native Object staticFieldBase(Field f);
-+
-+ /**
-+ * Ensure the given class has been initialized. This is often
-+ * needed in conjunction with obtaining the static field base of a
-+ * class.
-+ */
-+ public native void ensureClassInitialized(Class c);
-+
-+ /**
-+ * Report the offset of the first element in the storage allocation of a
-+ * given array class. If {@link #arrayIndexScale} returns a non-zero value
-+ * for the same class, you may use that scale factor, together with this
-+ * base offset, to form new offsets to access elements of arrays of the
-+ * given class.
-+ *
-+ * @see #getInt(Object, long)
-+ * @see #putInt(Object, long, int)
-+ */
-+ public native int arrayBaseOffset(Class arrayClass);
-+
-+ /** The value of {@code arrayBaseOffset(boolean[].class)} */
-+ public static final int ARRAY_BOOLEAN_BASE_OFFSET
-+ = theUnsafe.arrayBaseOffset(boolean[].class);
-+
-+ /** The value of {@code arrayBaseOffset(byte[].class)} */
-+ public static final int ARRAY_BYTE_BASE_OFFSET
-+ = theUnsafe.arrayBaseOffset(byte[].class);
-+
-+ /** The value of {@code arrayBaseOffset(short[].class)} */
-+ public static final int ARRAY_SHORT_BASE_OFFSET
-+ = theUnsafe.arrayBaseOffset(short[].class);
-+
-+ /** The value of {@code arrayBaseOffset(char[].class)} */
-+ public static final int ARRAY_CHAR_BASE_OFFSET
-+ = theUnsafe.arrayBaseOffset(char[].class);
-+
-+ /** The value of {@code arrayBaseOffset(int[].class)} */
-+ public static final int ARRAY_INT_BASE_OFFSET
-+ = theUnsafe.arrayBaseOffset(int[].class);
-+
-+ /** The value of {@code arrayBaseOffset(long[].class)} */
-+ public static final int ARRAY_LONG_BASE_OFFSET
-+ = theUnsafe.arrayBaseOffset(long[].class);
-+
-+ /** The value of {@code arrayBaseOffset(float[].class)} */
-+ public static final int ARRAY_FLOAT_BASE_OFFSET
-+ = theUnsafe.arrayBaseOffset(float[].class);
-+
-+ /** The value of {@code arrayBaseOffset(double[].class)} */
-+ public static final int ARRAY_DOUBLE_BASE_OFFSET
-+ = theUnsafe.arrayBaseOffset(double[].class);
-+
-+ /** The value of {@code arrayBaseOffset(Object[].class)} */
-+ public static final int ARRAY_OBJECT_BASE_OFFSET
-+ = theUnsafe.arrayBaseOffset(Object[].class);
-+
-+ /**
-+ * Report the scale factor for addressing elements in the storage
-+ * allocation of a given array class. However, arrays of "narrow" types
-+ * will generally not work properly with accessors like {@link
-+ * #getByte(Object, int)}, so the scale factor for such classes is reported
-+ * as zero.
-+ *
-+ * @see #arrayBaseOffset
-+ * @see #getInt(Object, long)
-+ * @see #putInt(Object, long, int)
-+ */
-+ public native int arrayIndexScale(Class arrayClass);
-+
-+ /** The value of {@code arrayIndexScale(boolean[].class)} */
-+ public static final int ARRAY_BOOLEAN_INDEX_SCALE
-+ = theUnsafe.arrayIndexScale(boolean[].class);
-+
-+ /** The value of {@code arrayIndexScale(byte[].class)} */
-+ public static final int ARRAY_BYTE_INDEX_SCALE
-+ = theUnsafe.arrayIndexScale(byte[].class);
-+
-+ /** The value of {@code arrayIndexScale(short[].class)} */
-+ public static final int ARRAY_SHORT_INDEX_SCALE
-+ = theUnsafe.arrayIndexScale(short[].class);
-+
-+ /** The value of {@code arrayIndexScale(char[].class)} */
-+ public static final int ARRAY_CHAR_INDEX_SCALE
-+ = theUnsafe.arrayIndexScale(char[].class);
-+
-+ /** The value of {@code arrayIndexScale(int[].class)} */
-+ public static final int ARRAY_INT_INDEX_SCALE
-+ = theUnsafe.arrayIndexScale(int[].class);
-+
-+ /** The value of {@code arrayIndexScale(long[].class)} */
-+ public static final int ARRAY_LONG_INDEX_SCALE
-+ = theUnsafe.arrayIndexScale(long[].class);
-+
-+ /** The value of {@code arrayIndexScale(float[].class)} */
-+ public static final int ARRAY_FLOAT_INDEX_SCALE
-+ = theUnsafe.arrayIndexScale(float[].class);
-+
-+ /** The value of {@code arrayIndexScale(double[].class)} */
-+ public static final int ARRAY_DOUBLE_INDEX_SCALE
-+ = theUnsafe.arrayIndexScale(double[].class);
-+
-+ /** The value of {@code arrayIndexScale(Object[].class)} */
-+ public static final int ARRAY_OBJECT_INDEX_SCALE
-+ = theUnsafe.arrayIndexScale(Object[].class);
-+
-+ /**
-+ * Report the size in bytes of a native pointer, as stored via {@link
-+ * #putAddress}. This value will be either 4 or 8. Note that the sizes of
-+ * other primitive types (as stored in native memory blocks) is determined
-+ * fully by their information content.
-+ */
-+ public native int addressSize();
-+
-+ /** The value of {@code addressSize()} */
-+ public static final int ADDRESS_SIZE = theUnsafe.addressSize();
-+
-+ /**
-+ * Report the size in bytes of a native memory page (whatever that is).
-+ * This value will always be a power of two.
-+ */
-+ public native int pageSize();
-+
-+
-+ /// random trusted operations from JNI:
-+
-+ /**
-+ * Tell the VM to define a class, without security checks. By default, the
-+ * class loader and protection domain come from the caller's class.
-+ */
-+ public native Class defineClass(String name, byte[] b, int off, int len,
-+ ClassLoader loader,
-+ ProtectionDomain protectionDomain);
-+
-+ public native Class defineClass(String name, byte[] b, int off, int len);
-+
-+ /**
-+ * Define a class but do not make it known to the class loader or system dictionary.
-+ * <p>
-+ * For each CP entry, the corresponding CP patch must either be null or have
-+ * the a format that matches its tag:
-+ * <ul>
-+ * <li>Integer, Long, Float, Double: the corresponding wrapper object type from java.lang
-+ * <li>Utf8: a string (must have suitable syntax if used as signature or name)
-+ * <li>Class: any java.lang.Class object
-+ * <li>String: any object (not just a java.lang.String)
-+ * <li>InterfaceMethodRef: (NYI) a method handle to invoke in that call site's arguments
-+ * </ul>
-+ * @params hostClass context for linkage, access control, protection domain, and class loader
-+ * @params data bytes of a class file, a raw memory address b
-+ * @params length number of bytes in class file
-+ * @params cpPatches where non-null entries exist, they replace corresponding CP entries in data
-+ */
-+ public native Class defineAnonymousClass(Class hostClass, byte[] data, Object[] cpPatches);
-+
-+ /** Allocate an instance but do not run any constructor.
-+ Initializes the class if it has not yet been. */
-+ public native Object allocateInstance(Class cls)
-+ throws InstantiationException;
-+
-+ /** Lock the object. It must get unlocked via {@link #monitorExit}. */
-+ public native void monitorEnter(Object o);
-+
-+ /**
-+ * Unlock the object. It must have been locked via {@link
-+ * #monitorEnter}.
-+ */
-+ public native void monitorExit(Object o);
-+
-+ /**
-+ * Tries to lock the object. Returns true or false to indicate
-+ * whether the lock succeeded. If it did, the object must be
-+ * unlocked via {@link #monitorExit}.
-+ */
-+ public native boolean tryMonitorEnter(Object o);
-+
-+ /** Throw the exception without telling the verifier. */
-+ public native void throwException(Throwable ee);
-+
-+
-+ /**
-+ * Atomically update Java variable to <tt>x</tt> if it is currently
-+ * holding <tt>expected</tt>.
-+ * @return <tt>true</tt> if successful
-+ */
-+ public final native boolean compareAndSwapObject(Object o, long offset,
-+ Object expected,
-+ Object x);
-+
-+ /**
-+ * Atomically update Java variable to <tt>x</tt> if it is currently
-+ * holding <tt>expected</tt>.
-+ * @return <tt>true</tt> if successful
-+ */
-+ public final native boolean compareAndSwapInt(Object o, long offset,
-+ int expected,
-+ int x);
-+
-+ /**
-+ * Atomically update Java variable to <tt>x</tt> if it is currently
-+ * holding <tt>expected</tt>.
-+ * @return <tt>true</tt> if successful
-+ */
-+ public final native boolean compareAndSwapLong(Object o, long offset,
-+ long expected,
-+ long x);
-+
-+ /**
-+ * Fetches a reference value from a given Java variable, with volatile
-+ * load semantics. Otherwise identical to {@link #getObject(Object, long)}
-+ */
-+ public native Object getObjectVolatile(Object o, long offset);
-+
-+ /**
-+ * Stores a reference value into a given Java variable, with
-+ * volatile store semantics. Otherwise identical to {@link #putObject(Object, long, Object)}
-+ */
-+ public native void putObjectVolatile(Object o, long offset, Object x);
-+
-+ /** Volatile version of {@link #getInt(Object, long)} */
-+ public native int getIntVolatile(Object o, long offset);
-+
-+ /** Volatile version of {@link #putInt(Object, long, int)} */
-+ public native void putIntVolatile(Object o, long offset, int x);
-+
-+ /** Volatile version of {@link #getBoolean(Object, long)} */
-+ public native boolean getBooleanVolatile(Object o, long offset);
-+
-+ /** Volatile version of {@link #putBoolean(Object, long, boolean)} */
-+ public native void putBooleanVolatile(Object o, long offset, boolean x);
-+
-+ /** Volatile version of {@link #getByte(Object, long)} */
-+ public native byte getByteVolatile(Object o, long offset);
-+
-+ /** Volatile version of {@link #putByte(Object, long, byte)} */
-+ public native void putByteVolatile(Object o, long offset, byte x);
-+
-+ /** Volatile version of {@link #getShort(Object, long)} */
-+ public native short getShortVolatile(Object o, long offset);
-+
-+ /** Volatile version of {@link #putShort(Object, long, short)} */
-+ public native void putShortVolatile(Object o, long offset, short x);
-+
-+ /** Volatile version of {@link #getChar(Object, long)} */
-+ public native char getCharVolatile(Object o, long offset);
-+
-+ /** Volatile version of {@link #putChar(Object, long, char)} */
-+ public native void putCharVolatile(Object o, long offset, char x);
-+
-+ /** Volatile version of {@link #getLong(Object, long)} */
-+ public native long getLongVolatile(Object o, long offset);
-+
-+ /** Volatile version of {@link #putLong(Object, long, long)} */
-+ public native void putLongVolatile(Object o, long offset, long x);
-+
-+ /** Volatile version of {@link #getFloat(Object, long)} */
-+ public native float getFloatVolatile(Object o, long offset);
-+
-+ /** Volatile version of {@link #putFloat(Object, long, float)} */
-+ public native void putFloatVolatile(Object o, long offset, float x);
-+
-+ /** Volatile version of {@link #getDouble(Object, long)} */
-+ public native double getDoubleVolatile(Object o, long offset);
-+
-+ /** Volatile version of {@link #putDouble(Object, long, double)} */
-+ public native void putDoubleVolatile(Object o, long offset, double x);
-+
-+ /**
-+ * Version of {@link #putObjectVolatile(Object, long, Object)}
-+ * that does not guarantee immediate visibility of the store to
-+ * other threads. This method is generally only useful if the
-+ * underlying field is a Java volatile (or if an array cell, one
-+ * that is otherwise only accessed using volatile accesses).
-+ */
-+ public native void putOrderedObject(Object o, long offset, Object x);
-+
-+ /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */
-+ public native void putOrderedInt(Object o, long offset, int x);
-+
-+ /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */
-+ public native void putOrderedLong(Object o, long offset, long x);
-+
-+ /**
-+ * Unblock the given thread blocked on <tt>park</tt>, or, if it is
-+ * not blocked, cause the subsequent call to <tt>park</tt> not to
-+ * block. Note: this operation is "unsafe" solely because the
-+ * caller must somehow ensure that the thread has not been
-+ * destroyed. Nothing special is usually required to ensure this
-+ * when called from Java (in which there will ordinarily be a live
-+ * reference to the thread) but this is not nearly-automatically
-+ * so when calling from native code.
-+ * @param thread the thread to unpark.
-+ *
-+ */
-+ public native void unpark(Object thread);
-+
-+ /**
-+ * Block current thread, returning when a balancing
-+ * <tt>unpark</tt> occurs, or a balancing <tt>unpark</tt> has
-+ * already occurred, or the thread is interrupted, or, if not
-+ * absolute and time is not zero, the given time nanoseconds have
-+ * elapsed, or if absolute, the given deadline in milliseconds
-+ * since Epoch has passed, or spuriously (i.e., returning for no
-+ * "reason"). Note: This operation is in the Unsafe class only
-+ * because <tt>unpark</tt> is, so it would be strange to place it
-+ * elsewhere.
-+ */
-+ public native void park(boolean isAbsolute, long time);
-+
-+ /**
-+ * Gets the load average in the system run queue assigned
-+ * to the available processors averaged over various periods of time.
-+ * This method retrieves the given <tt>nelem</tt> samples and
-+ * assigns to the elements of the given <tt>loadavg</tt> array.
-+ * The system imposes a maximum of 3 samples, representing
-+ * averages over the last 1, 5, and 15 minutes, respectively.
-+ *
-+ * @params loadavg an array of double of size nelems
-+ * @params nelems the number of samples to be retrieved and
-+ * must be 1 to 3.
-+ *
-+ * @return the number of samples actually retrieved; or -1
-+ * if the load average is unobtainable.
-+ */
-+ public native int getLoadAverage(double[] loadavg, int nelems);
-+}
-diff --git a/src/share/projects/anonk/src/sun/reflect/Reflection.java b/src/share/projects/anonk/src/sun/reflect/Reflection.java
-new file mode 100644
---- /dev/null
-+++ b/src/share/projects/anonk/src/sun/reflect/Reflection.java
-@@ -0,0 +1,325 @@
-+/*
-+ * Copyright 2001-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. 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.reflect;
-+
-+import java.lang.reflect.*;
-+import java.util.Collections;
-+import java.util.HashMap;
-+import java.util.Map;
-+
-+/** Common utility routines used by both java.lang and
-+ java.lang.reflect */
-+
-+public class Reflection {
-+
-+ /** Used to filter out fields and methods from certain classes from public
-+ view, where they are sensitive or they may contain VM-internal objects.
-+ These Maps are updated very rarely. Rather than synchronize on
-+ each access, we use copy-on-write */
-+ private static volatile Map<Class,String[]> fieldFilterMap;
-+ private static volatile Map<Class,String[]> methodFilterMap;
-+
-+ static {
-+ Map<Class,String[]> map = new HashMap<Class,String[]>();
-+ map.put(Reflection.class,
-+ new String[] {"fieldFilterMap", "methodFilterMap"});
-+ map.put(System.class, new String[] {"security"});
-+ fieldFilterMap = map;
-+
-+ methodFilterMap = new HashMap<Class,String[]>();
-+ }
-+
-+ /** Returns the class of the method <code>realFramesToSkip</code>
-+ frames up the stack (zero-based), ignoring frames associated
-+ with java.lang.reflect.Method.invoke() and its implementation.
-+ The first frame is that associated with this method, so
-+ <code>getCallerClass(0)</code> returns the Class object for
-+ sun.reflect.Reflection. Frames associated with
-+ java.lang.reflect.Method.invoke() and its implementation are
-+ completely ignored and do not count toward the number of "real"
-+ frames skipped. */
-+ public static native Class getCallerClass(int realFramesToSkip);
-+
-+ /** Retrieves the access flags written to the class file. For
-+ inner classes these flags may differ from those returned by
-+ Class.getModifiers(), which searches the InnerClasses
-+ attribute to find the source-level access flags. This is used
-+ instead of Class.getModifiers() for run-time access checks due
-+ to compatibility reasons; see 4471811. Only the values of the
-+ low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
-+ valid. */
-+ private static native int getClassAccessFlags(Class c);
-+
-+ /** A quick "fast-path" check to try to avoid getCallerClass()
-+ calls. */
-+ public static boolean quickCheckMemberAccess(Class memberClass,
-+ int modifiers)
-+ {
-+ return Modifier.isPublic(getClassAccessFlags(memberClass) & modifiers);
-+ }
-+
-+ public static void ensureMemberAccess(Class currentClass,
-+ Class memberClass,
-+ Object target,
-+ int modifiers)
-+ throws IllegalAccessException
-+ {
-+ if (currentClass == null || memberClass == null) {
-+ throw new InternalError();
-+ }
-+
-+ if (!verifyMemberAccess(currentClass, memberClass, target, modifiers)) {
-+ throw new IllegalAccessException("Class " + currentClass.getName() +
-+ " can not access a member of class " +
-+ memberClass.getName() +
-+ " with modifiers \"" +
-+ Modifier.toString(modifiers) +
-+ "\"");
-+ }
-+ }
-+
-+ public static boolean verifyMemberAccess(Class currentClass,
-+ // Declaring class of field
-+ // or method
-+ Class memberClass,
-+ // May be NULL in case of statics
-+ Object target,
-+ int modifiers)
-+ {
-+ // Verify that currentClass can access a field, method, or
-+ // constructor of memberClass, where that member's access bits are
-+ // "modifiers".
-+
-+ boolean gotIsSameClassPackage = false;
-+ boolean isSameClassPackage = false;
-+
-+ if (currentClass == memberClass) {
-+ // Always succeeds
-+ return true;
-+ }
-+
-+ if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
-+ isSameClassPackage = isSameClassPackage(currentClass, memberClass);
-+ gotIsSameClassPackage = true;
-+ if (!isSameClassPackage) {
-+ return false;
-+ }
-+ }
-+
-+ // At this point we know that currentClass can access memberClass.
-+
-+ if (Modifier.isPublic(modifiers)) {
-+ return true;
-+ }
-+
-+ boolean successSoFar = false;
-+
-+ if (Modifier.isProtected(modifiers)) {
-+ // See if currentClass is a subclass of memberClass
-+ if (isSubclassOf(currentClass, memberClass)) {
-+ successSoFar = true;
-+ }
-+ }
-+
-+ if (!successSoFar && !Modifier.isPrivate(modifiers)) {
-+ if (!gotIsSameClassPackage) {
-+ isSameClassPackage = isSameClassPackage(currentClass,
-+ memberClass);
-+ gotIsSameClassPackage = true;
-+ }
-+
-+ if (isSameClassPackage) {
-+ successSoFar = true;
-+ }
-+ }
-+
-+ if (!successSoFar) {
-+ return false;
-+ }
-+
-+ if (Modifier.isProtected(modifiers)) {
-+ // Additional test for protected members: JLS 6.6.2
-+ Class targetClass = (target == null ? memberClass : target.getClass());
-+ if (targetClass != currentClass) {
-+ if (!gotIsSameClassPackage) {
-+ isSameClassPackage = isSameClassPackage(currentClass, memberClass);
-+ gotIsSameClassPackage = true;
-+ }
-+ if (!isSameClassPackage) {
-+ if (!isSubclassOf(targetClass, currentClass)) {
-+ return false;
-+ }
-+ }
-+ }
-+ }
-+
-+ return true;
-+ }
-+
-+ private static boolean isSameClassPackage(Class c1, Class c2) {
-+ return isSameClassPackage(c1.getClassLoader(), c1.getName(),
-+ c2.getClassLoader(), c2.getName());
-+ }
-+
-+ /** Returns true if two classes are in the same package; classloader
-+ and classname information is enough to determine a class's package */
-+ private static boolean isSameClassPackage(ClassLoader loader1, String name1,
-+ ClassLoader loader2, String name2)
-+ {
-+ if (loader1 != loader2) {
-+ return false;
-+ } else {
-+ int lastDot1 = name1.lastIndexOf('.');
-+ int lastDot2 = name2.lastIndexOf('.');
-+ if ((lastDot1 == -1) || (lastDot2 == -1)) {
-+ // One of the two doesn't have a package. Only return true
-+ // if the other one also doesn't have a package.
-+ return (lastDot1 == lastDot2);
-+ } else {
-+ int idx1 = 0;
-+ int idx2 = 0;
-+
-+ // Skip over '['s
-+ if (name1.charAt(idx1) == '[') {
-+ do {
-+ idx1++;
-+ } while (name1.charAt(idx1) == '[');
-+ if (name1.charAt(idx1) != 'L') {
-+ // Something is terribly wrong. Shouldn't be here.
-+ throw new InternalError("Illegal class name " + name1);
-+ }
-+ }
-+ if (name2.charAt(idx2) == '[') {
-+ do {
-+ idx2++;
-+ } while (name2.charAt(idx2) == '[');
-+ if (name2.charAt(idx2) != 'L') {
-+ // Something is terribly wrong. Shouldn't be here.
-+ throw new InternalError("Illegal class name " + name2);
-+ }
-+ }
-+
-+ // Check that package part is identical
-+ int length1 = lastDot1 - idx1;
-+ int length2 = lastDot2 - idx2;
-+
-+ if (length1 != length2) {
-+ return false;
-+ }
-+ return name1.regionMatches(false, idx1, name2, idx2, length1);
-+ }
-+ }
-+ }
-+
-+ static boolean isSubclassOf(Class queryClass,
-+ Class ofClass)
-+ {
-+ while (queryClass != null) {
-+ if (queryClass == ofClass) {
-+ return true;
-+ }
-+ queryClass = queryClass.getSuperclass();
-+ }
-+ return false;
-+ }
-+
-+ // fieldNames must contain only interned Strings
-+ public static synchronized void registerFieldsToFilter(Class containingClass,
-+ String ... fieldNames) {
-+ fieldFilterMap =
-+ registerFilter(fieldFilterMap, containingClass, fieldNames);
-+ }
-+
-+ // methodNames must contain only interned Strings
-+ public static synchronized void registerMethodsToFilter(Class containingClass,
-+ String ... methodNames) {
-+ methodFilterMap =
-+ registerFilter(methodFilterMap, containingClass, methodNames);
-+ }
-+
-+ private static Map<Class,String[]> registerFilter(Map<Class,String[]> map,
-+ Class containingClass, String ... names) {
-+ if (map.get(containingClass) != null) {
-+ throw new IllegalArgumentException
-+ ("Filter already registered: " + containingClass);
-+ }
-+ map = new HashMap<Class,String[]>(map);
-+ map.put(containingClass, names);
-+ return map;
-+ }
-+
-+ public static Field[] filterFields(Class containingClass,
-+ Field[] fields) {
-+ if (fieldFilterMap == null) {
-+ // Bootstrapping
-+ return fields;
-+ }
-+ return (Field[])filter(fields, fieldFilterMap.get(containingClass));
-+ }
-+
-+ public static Method[] filterMethods(Class containingClass, Method[] methods) {
-+ if (methodFilterMap == null) {
-+ // Bootstrapping
-+ return methods;
-+ }
-+ return (Method[])filter(methods, methodFilterMap.get(containingClass));
-+ }
-+
-+ private static Member[] filter(Member[] members, String[] filteredNames) {
-+ if ((filteredNames == null) || (members.length == 0)) {
-+ return members;
-+ }
-+ int numNewMembers = 0;
-+ for (Member member : members) {
-+ boolean shouldSkip = false;
-+ for (String filteredName : filteredNames) {
-+ if (member.getName() == filteredName) {
-+ shouldSkip = true;
-+ break;
-+ }
-+ }
-+ if (!shouldSkip) {
-+ ++numNewMembers;
-+ }
-+ }
-+ Member[] newMembers =
-+ (Member[])Array.newInstance(members[0].getClass(), numNewMembers);
-+ int destIdx = 0;
-+ for (Member member : members) {
-+ boolean shouldSkip = false;
-+ for (String filteredName : filteredNames) {
-+ if (member.getName() == filteredName) {
-+ shouldSkip = true;
-+ break;
-+ }
-+ }
-+ if (!shouldSkip) {
-+ newMembers[destIdx++] = member;
-+ }
-+ }
-+ return newMembers;
-+ }
-+}
diff --git a/src/share/projects/anonk/test/jdk/java/dyn/AnonymousTest.java b/src/share/projects/anonk/test/jdk/java/dyn/AnonymousTest.java
new file mode 100644
--- /dev/null