summaryrefslogtreecommitdiff
path: root/libjava/classpath/vm/reference/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/vm/reference/gnu')
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java131
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java97
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/jdwp/VMFrame.java135
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/jdwp/VMIdManager.java435
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/jdwp/VMMethod.java189
-rw-r--r--libjava/classpath/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java425
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/VMCPStringBuilder.java112
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/VMInstrumentationImpl.java108
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMClassLoadingMXBeanImpl.java89
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMCompilationMXBeanImpl.java66
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java80
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryMXBeanImpl.java156
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java95
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java195
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java68
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMRuntimeMXBeanImpl.java89
-rw-r--r--libjava/classpath/vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java236
-rw-r--r--libjava/classpath/vm/reference/gnu/java/net/VMPlainDatagramSocketImpl.java260
-rw-r--r--libjava/classpath/vm/reference/gnu/java/net/VMPlainSocketImpl.java511
-rw-r--r--libjava/classpath/vm/reference/gnu/java/nio/VMChannel.java749
-rw-r--r--libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java80
-rw-r--r--libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java59
-rw-r--r--libjava/classpath/vm/reference/gnu/java/security/jce/prng/VMSecureRandom.java129
23 files changed, 4494 insertions, 0 deletions
diff --git a/libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java b/libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java
new file mode 100644
index 000000000..2214e7571
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/VMStackWalker.java
@@ -0,0 +1,131 @@
+/* VMStackWalker.java -- Reference implementation of VM hooks for stack access
+ Copyright (C) 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.classpath;
+
+/**
+ * This class provides access to the classes on the Java stack
+ * for reflection and security purposes.
+ *
+ * <p>
+ * This class is only available to privileged code (i.e., code loaded
+ * by the bootstrap loader).
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Archie Cobbs
+ */
+public final class VMStackWalker
+{
+ /**
+ * Get a list of all the classes currently executing methods on the
+ * Java stack. <code>getClassContext()[0]</code> is the class associated
+ * with the currently executing method, i.e., the method that called
+ * <code>VMStackWalker.getClassContext()</code> (possibly through
+ * reflection). So you may need to pop off these stack frames from
+ * the top of the stack:
+ * <ul>
+ * <li><code>VMStackWalker.getClassContext()</code>
+ * <li><code>Method.invoke()</code>
+ * </ul>
+ *
+ * @return an array of the declaring classes of each stack frame
+ */
+ public static native Class[] getClassContext();
+
+ /**
+ * Get the class associated with the method invoking the method
+ * invoking this method, or <code>null</code> if the stack is not
+ * that deep (e.g., invoked via JNI invocation API). This method
+ * is an optimization for the expression <code>getClassContext()[1]</code>
+ * and should return the same result.
+ *
+ * <p>
+ * VM implementers are encouraged to provide a more efficient
+ * version of this method.
+ */
+ public static Class getCallingClass()
+ {
+ Class[] ctx = getClassContext();
+ if (ctx.length < 3)
+ return null;
+ return ctx[2];
+ }
+
+ /**
+ * Get the class loader associated with the Class returned by
+ * <code>getCallingClass()</code>, or <code>null</code> if no such class
+ * exists or it is the boot loader. This method is an optimization for the
+ * expression <code>VMStackWalker.getClassLoader(getClassContext()[1])</code>
+ * and should return the same result.
+ *
+ * <p>
+ * VM implementers are encouraged to provide a more efficient
+ * version of this method.
+ */
+ public static ClassLoader getCallingClassLoader()
+ {
+ Class[] ctx = getClassContext();
+ if (ctx.length < 3)
+ return null;
+ return getClassLoader(ctx[2]);
+ }
+
+ /**
+ * Retrieve the class's ClassLoader, or <code>null</code> if loaded
+ * by the bootstrap loader. I.e., this should return the same thing
+ * as {@link java.lang.VMClass#getClassLoader}. This duplicate version
+ * is here to work around access permissions.
+ */
+ public static native ClassLoader getClassLoader(Class cl);
+
+ /**
+ * Walk up the stack and return the first non-null class loader.
+ * If there aren't any non-null class loaders on the stack, return null.
+ */
+ public static ClassLoader firstNonNullClassLoader()
+ {
+ Class[] stack = getClassContext();
+ for (int i = 0; i < stack.length; i++)
+ {
+ ClassLoader loader = getClassLoader(stack[i]);
+ if (loader != null)
+ return loader;
+ }
+ return null;
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java b/libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java
new file mode 100644
index 000000000..1e0dd4e26
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/VMSystemProperties.java
@@ -0,0 +1,97 @@
+/* VMSystemProperties.java -- Allow the VM to set System properties.
+ Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.classpath;
+
+import java.util.Properties;
+
+class VMSystemProperties
+{
+ /**
+ * Get the system properties. This is done here, instead of in System,
+ * because of the bootstrap sequence. Note that the native code should
+ * not try to use the Java I/O classes yet, as they rely on the properties
+ * already existing. The only safe method to use to insert these default
+ * system properties is {@link Properties#setProperty(String, String)}.
+ *
+ * <p>These properties MUST include:
+ * <dl>
+ * <dt>java.version <dd>Java version number
+ * <dt>java.vendor <dd>Java vendor specific string
+ * <dt>java.vendor.url <dd>Java vendor URL
+ * <dt>java.home <dd>Java installation directory
+ * <dt>java.vm.specification.version <dd>VM Spec version
+ * <dt>java.vm.specification.vendor <dd>VM Spec vendor
+ * <dt>java.vm.specification.name <dd>VM Spec name
+ * <dt>java.vm.version <dd>VM implementation version
+ * <dt>java.vm.vendor <dd>VM implementation vendor
+ * <dt>java.vm.name <dd>VM implementation name
+ * <dt>java.specification.version <dd>Java Runtime Environment version
+ * <dt>java.specification.vendor <dd>Java Runtime Environment vendor
+ * <dt>java.specification.name <dd>Java Runtime Environment name
+ * <dt>java.class.version <dd>Java class version number
+ * <dt>java.class.path <dd>Java classpath
+ * <dt>java.library.path <dd>Path for finding Java libraries
+ * <dt>java.io.tmpdir <dd>Default temp file path
+ * <dt>java.compiler <dd>Name of JIT to use
+ * <dt>java.ext.dirs <dd>Java extension path
+ * <dt>os.name <dd>Operating System Name
+ * <dt>os.arch <dd>Operating System Architecture
+ * <dt>os.version <dd>Operating System Version
+ * <dt>file.separator <dd>File separator ("/" on Unix)
+ * <dt>path.separator <dd>Path separator (":" on Unix)
+ * <dt>line.separator <dd>Line separator ("\n" on Unix)
+ * <dt>user.name <dd>User account name
+ * <dt>user.home <dd>User home directory
+ * <dt>user.dir <dd>User's current working directory
+ * <dt>gnu.cpu.endian <dd>"big" or "little"
+ * </dl>
+ *
+ * @param properties the Properties object to insert the system properties into
+ */
+ static native void preInit(Properties properties);
+
+ /**
+ * Here you get a chance to overwrite some of the properties set by
+ * the common SystemProperties code. For example, it might be
+ * a good idea to process the properties specified on the command
+ * line here.
+ */
+ static void postInit(Properties properties)
+ {
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMFrame.java b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMFrame.java
new file mode 100644
index 000000000..6419d3ee9
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMFrame.java
@@ -0,0 +1,135 @@
+/* VMFrame.java -- Reference implementation of VM hooks for JDWP Frame access.
+ Copyright (C) 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath.jdwp;
+
+import gnu.classpath.jdwp.util.Location;
+import gnu.classpath.jdwp.value.Value;
+
+/**
+ * Reference implementation of VM hooks for JDWP Frame access.
+ *
+ * @author aluchko
+ */
+
+public class VMFrame
+{
+ /**
+ * Returns the size of a frame ID over JDWP
+ */
+ public static final int SIZE = 8;
+
+ //The thread this frame resides in
+ private Thread thread;
+
+ // The object this frame resides in
+ private Object obj;
+
+ // The current location of this frame
+ private Location loc;
+
+ // id of this frame
+ private long id;
+
+ /**
+ * Create a new VMFrame object.
+ *
+ * @param thr a Thread, the thread this frame is in
+ * @param frame_id a long, the jframeID of this frame
+ * @param frame_loc a Location, the location of this frame
+ * @param frame_obj the "this" object of this frame
+ */
+ public VMFrame(Thread thr, long frame_id, Location frame_loc,
+ Object frame_obj)
+ {
+ thread = thr;
+ id = frame_id;
+ loc = frame_loc;
+ obj = frame_obj;
+ }
+
+ /**
+ * Gets the current location of the frame.
+ */
+ public Location getLocation()
+ {
+ return loc;
+ }
+
+ /**
+ * Returns the value of the variable in the given slot.
+ *
+ * @param slot the slot containing the variable
+ */
+ public native Value getValue(int slot, byte sig);
+
+ /**
+ * Assigns the given variable to the given value.
+ * @param slot The slot which contains the variable
+ * @param value The value to assign the variable to
+ */
+ public native void setValue(int slot, Value value);
+
+ /**
+ * Get the thread this frame is in.
+ */
+ public Thread getThread()
+ {
+ return thread;
+ }
+
+ /**
+ * Get the object which is represented by 'this' in the context of the frame,
+ * returns null if the method is native or static.
+ */
+ public Object getObject()
+ {
+ return obj;
+ }
+
+ /**
+ * Get the frameID
+ * @return an id which is unique within the scope of the VM
+ */
+ public long getId()
+ {
+ return id;
+ }
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMIdManager.java b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMIdManager.java
new file mode 100644
index 000000000..ac3e05a7c
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMIdManager.java
@@ -0,0 +1,435 @@
+/* VMIdManager.java -- A reference/example implementation of a manager for
+ JDWP object/reference type IDs
+
+ Copyright (C) 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath.jdwp;
+
+import gnu.classpath.jdwp.exception.InvalidClassException;
+import gnu.classpath.jdwp.exception.InvalidObjectException;
+import gnu.classpath.jdwp.id.*;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Hashtable;
+
+/**
+ * This class manages objects and referencetypes that are reported
+ * to the debugger. All objects and referencetypes reported to the
+ * debugger should go through this manager.
+ *
+ * A brief summary of what an <code>IdManager</code> must provide:
+ *
+ * <code>
+ * public ObjectId getObjectId (Object theObject);
+ * public ObjectId get (long id);
+ * public ObjectId readObjectId (ByteBuffer bb);
+ * public ReferenceTypeId getReferenceTypeId (Class clazz);
+ * public ReferenceTypeId getReferenceType (long id);
+ * public ReferenceTypeId readReferenceTypeId (ByteBuffer bb);
+ * </code>
+ *
+ * See the javadoc on these methods later in this file for more
+ * information on these functions.
+ *
+ * <b>NOTE:</b> All IDs handled by the ID manager (all object and reference
+ * type IDs) are assumed to be of type <code>long</code>.
+ *
+ * <b>NOTE:</b> This class does not manage virtual machine-specific types,
+ * like methods, fields, and frames. These already have unique IDs within
+ * the virtual machine and do not need further abstraction here.
+ *
+ * @author Keith Seitz (keiths@redhat.com)
+ */
+public class VMIdManager
+{
+ // This factory generates ids for objects and types that may
+ // be sent to a debugger.
+ private static class IdFactory
+ {
+ // ID of last object / referencetype
+ private static Object _idLock = new Object ();
+ private static Object _ridLock = new Object ();
+ private static long _lastId = 0;
+ private static long _lastRid = 0;
+
+ // A list of all ID types
+ private static HashMap _idList = new HashMap ();
+
+ // Initialize the id list with known types
+ static
+ {
+ // ObjectId and ArrayId are special cases. See newObjectId.
+ _idList.put (ClassLoaderId.typeClass, ClassLoaderId.class);
+ _idList.put (ClassObjectId.typeClass, ClassObjectId.class);
+ _idList.put (StringId.typeClass, StringId.class);
+ _idList.put (ThreadId.typeClass, ThreadId.class);
+ _idList.put (ThreadGroupId.typeClass, ThreadGroupId.class);
+ }
+
+ /**
+ * Returns a new id for the given object
+ *
+ * @param obj SoftReference of the object for which an id is desired
+ * @returns a suitable object id
+ */
+ public static ObjectId newObjectId (SoftReference obj)
+ {
+ ObjectId id = null;
+ Object object = obj.get ();
+
+ // Special case: arrays
+ if (object.getClass ().isArray ())
+ id = new ArrayId ();
+ else
+ {
+ // Loop through all classes until we hit baseclass
+ Class myClass;
+ for (myClass = object.getClass (); myClass != null;
+ myClass = myClass.getSuperclass ())
+ {
+ Class clz = (Class) _idList.get (myClass);
+ if (clz != null)
+ {
+ try
+ {
+ id = (ObjectId) clz.newInstance ();
+ synchronized (_idLock)
+ {
+ id.setId (++_lastId);
+ }
+ id.setReference (obj);
+ return id;
+ }
+ catch (InstantiationException ie)
+ {
+ // This really should not happen
+ throw new RuntimeException ("cannot create new ID", ie);
+ }
+ catch (IllegalAccessException iae)
+ {
+ // This really should not happen
+ throw new RuntimeException ("illegal access of ID", iae);
+ }
+ }
+ }
+
+ /* getSuperclass returned null and no matching ID type found.
+ So it must derive from Object. */
+ id = new ObjectId ();
+ }
+
+ synchronized (_idLock)
+ {
+ id.setId (++_lastId);
+ }
+ id.setReference (obj);
+ return id;
+ }
+
+ /**
+ * Returns a new reference type id for the given class
+ *
+ * @param ref SoftReference to the desired type
+ * @returns a suitable reference type id or null when the
+ * reference is cleared.
+ */
+ public static ReferenceTypeId newReferenceTypeId (SoftReference ref)
+ {
+ ReferenceTypeId id;
+ Class clazz = (Class) ref.get ();
+ if (clazz == null)
+ return null;
+
+ if (clazz.isArray ())
+ id = new ArrayReferenceTypeId ();
+ else if (clazz.isInterface ())
+ id = new InterfaceReferenceTypeId ();
+ else
+ id = new ClassReferenceTypeId ();
+ id.setReference (ref);
+ synchronized (_ridLock)
+ {
+ id.setId (++_lastRid);
+ }
+ return id;
+ }
+ }
+
+ /**
+ * This class is a SoftReferenceIdentity type that is used by
+ * the ID manager.
+ */
+ class ReferenceKey extends SoftReference
+ {
+ // Hash code of referent
+ private int _hash;
+
+ /**
+ * Constructs a new <code>ReferenceKey</code> object
+ * with the given referent.
+ *
+ * <p>This constructor should only be used for object lookups
+ * by the backend.
+ *
+ * @param referent the object to reference
+ */
+ public ReferenceKey (Object referent)
+ {
+ super (referent);
+ _hash = referent.hashCode ();
+ }
+
+ /**
+ * Constructs a new <code>ReferenceKey</code> object
+ * with the given referent and reference queue.
+ *
+ * <p>The JDWP back-end stores a <code>ReferenceKey</code>
+ * with its corresponding <code>JdwpId</code>. This constructor
+ * is used by the back-end when adding new IDs to be managed.
+ *
+ * @param referent the object to reference
+ * @param queue the queue to which to report garbage collections
+ */
+ public ReferenceKey (Object referent, ReferenceQueue queue)
+ {
+ super (referent, queue);
+ _hash = referent.hashCode ();
+ }
+
+ /**
+ * Returns the hash code of the referent.
+ * This seems hacky, but is required in order to use this class
+ * as a hash table key.
+ *
+ * @returns the hash code of the referent
+ */
+ public int hashCode ()
+ {
+ return _hash;
+ }
+
+ /**
+ * Comparator for keys
+ *
+ * This method can be used in two ways:
+ *
+ * <ol>
+ * <li>For table lookups, where we want to compare referents</li>
+ * <li>For clearing GCd objects, where we want to compare the actual
+ * key object (not the referent)</li>
+ * </ol>
+ */
+ public boolean equals (Object obj)
+ {
+ if (obj instanceof ReferenceKey)
+ {
+ ReferenceKey ref = (ReferenceKey) obj;
+
+ /* First check if the two references are the same.
+ If they are, that means we must be clearing GCd objects. */
+ if (this == obj)
+ return true;
+
+ return (ref.get () == get ());
+ }
+
+ return false;
+ }
+ }
+
+ // instance of VMIdManager
+ private static VMIdManager _idm = new VMIdManager ();
+
+ // A reference queue for our objects
+ private ReferenceQueue _refQueue;
+
+ // Mapping of objects (ReferenceKey) to IDs (ObjectId)
+ private Hashtable _oidTable;
+
+ // Mapping of ID numbers (Long) to IDs (ObjectId)
+ private Hashtable _idTable;
+
+ /* Mapping of class (ReferenceKey) to IDs (ReferenceTypeId) for reference
+ types. Unlike other types, reference id types are NEVER released. */
+ private Hashtable _classTable;
+
+ // Mapping of ID numbers (Long) to reference type IDs (ReferenceTypeId)
+ private Hashtable _ridTable;
+
+ /**
+ * Gets the instance of VMIdManager, constructing a new one
+ * if none currently exists.
+ */
+ public static VMIdManager getDefault ()
+ {
+ return _idm;
+ }
+
+ // Constructs a new <code>IdManager</code>
+ private VMIdManager ()
+ {
+ _refQueue = new ReferenceQueue ();
+ _oidTable = new Hashtable (50);
+ _idTable = new Hashtable (50);
+ _classTable = new Hashtable (20);
+ _ridTable = new Hashtable (20);
+ }
+
+ // Updates the object ID table, removing IDs whose objects have
+ // been garbage collected.
+ private void _update ()
+ {
+ Reference ref;
+ while ((ref = _refQueue.poll ()) != null)
+ {
+ ObjectId id = (ObjectId) _oidTable.get (ref);
+ _oidTable.remove (ref);
+ _idTable.remove (new Long (id.getId ()));
+ }
+ }
+
+ /**
+ * Returns an id for the given object, adding it
+ * if it does not have an id.
+ *
+ * @param theObject the object to get an ID/add
+ * @returns the ID of the object
+ */
+ public ObjectId getObjectId (Object theObject)
+ {
+ // Special case: null
+ if (theObject == null)
+ return new NullObjectId ();
+
+ ReferenceKey ref = new ReferenceKey (theObject, _refQueue);
+ ObjectId id = (ObjectId) _oidTable.get (ref);
+ if (id == null)
+ {
+ // update the tables -- this is an arbitrary place to put this
+ _update ();
+
+ // Object not found. Make new id for it
+ id = IdFactory.newObjectId (ref);
+ _oidTable.put (ref, id);
+ _idTable.put (new Long (id.getId ()), id);
+ }
+
+ return id;
+ }
+
+ /**
+ * Returns the <code>JdwpId</code> for a given ID. Unlike
+ * <code>getId</code>, it throws an exception if the ID is not
+ * known.
+ *
+ * @param id the numerical ID of the desired <code>JdwpId</code>
+ * @throws InvalidObjectException if the ID is not found
+ */
+ public ObjectId get (long id)
+ throws InvalidObjectException
+ {
+ // Special case: null
+ if (id == 0)
+ return new NullObjectId ();
+
+ ObjectId oid = (ObjectId) _idTable.get (new Long (id));
+ if (oid == null)
+ throw new InvalidObjectException (id);
+
+ return oid;
+ }
+
+ public ObjectId readObjectId (ByteBuffer bb)
+ throws InvalidObjectException
+ {
+ long id = bb.getLong ();
+ return get (id);
+ }
+
+ /**
+ * Gets the reference type id for the given class, creating
+ * a new one if it does not already have an id
+ *
+ * @param clazz the class for which to get an ID
+ * @returns the ID of the class
+ */
+ public ReferenceTypeId getReferenceTypeId (Class clazz)
+ {
+ ReferenceKey ref = new ReferenceKey (clazz);
+ ReferenceTypeId id = (ReferenceTypeId)_classTable.get (ref);
+ if (id == null)
+ {
+ // Object not found. Make new id for it
+ id = IdFactory.newReferenceTypeId (ref);
+ _classTable.put (ref, id);
+ _ridTable.put (new Long (id.getId ()), id);
+ }
+
+ return id;
+ }
+
+ /**
+ * Returns the <code>ReferenceTypeId</code> for a given ID. Unlike
+ * <code>getReferenceTypeId</code>, it throws an exception if the ID is not
+ * known.
+ *
+ * @param id the numerical ID of the desired reference type
+ * @throws InvalidClassException if the ID is not found
+ */
+ public ReferenceTypeId getReferenceType (long id)
+ throws InvalidClassException
+ {
+ ReferenceTypeId rid = (ReferenceTypeId) _ridTable.get (new Long (id));
+ if (rid == null)
+ throw new InvalidClassException (id);
+
+ return rid;
+ }
+
+ public ReferenceTypeId readReferenceTypeId (ByteBuffer bb)
+ throws InvalidClassException
+ {
+ long id = bb.getLong ();
+ return getReferenceType (id);
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMMethod.java b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMMethod.java
new file mode 100644
index 000000000..8e15a48d1
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMMethod.java
@@ -0,0 +1,189 @@
+/* VMMethod.java -- a method in a virtual machine
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath.jdwp;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import gnu.classpath.jdwp.exception.JdwpException;
+import gnu.classpath.jdwp.util.LineTable;
+import gnu.classpath.jdwp.util.VariableTable;
+
+/**
+ * This class is really an amalgamation of two classes: one class
+ * represents a virtual machine method and the other represents
+ * the JDWP back-end's ID for the method.
+ *
+ * @author Keith Seitz (keiths@redhat.com)
+ */
+public class VMMethod
+{
+ /**
+ * Returns the size of a JDWP method ID
+ * @see gnu.classpath.jdwp.id.JdwpId#SIZE
+ */
+ public static final int SIZE = 8;
+
+ // The class in which this method is declared
+ private Class _class;
+
+ // The method's ID
+ private long _methodId;
+
+ /**
+ * Constructs a new VMMethod object. This constructor is protected
+ * so that only the factory methods of VMVirtualMachine can be used
+ * to create VMMethods.
+ *
+ * @param klass the method's containing class
+ * @param id method identifier, e.g., jmethodID
+ * @see gnu.classpath.jdwp.VMVirtualMachine#getAllClassMethods
+ * @see gnu.classpath.jdwp.VMVirtualMachine#getClassMethod
+ */
+ protected VMMethod(Class klass, long id)
+ {
+ _class = klass;
+ _methodId = id;
+ }
+
+ /**
+ * Returns the internal method ID for this method
+ */
+ public long getId()
+ {
+ return _methodId;
+ }
+
+ /**
+ * Returns the method's declaring class
+ */
+ public Class getDeclaringClass()
+ {
+ return _class;
+ }
+
+ /**
+ * Returns the name of this method
+ */
+ public native String getName();
+
+ /**
+ * Returns the signature of this method
+ */
+ public native String getSignature();
+
+ /**
+ * Returns the method's modifier flags
+ */
+ public native int getModifiers();
+
+ /**
+ * "Returns line number information for the method, if present. The line
+ * table maps source line numbers to the initial code index of the line.
+ * The line table is ordered by code index (from lowest to highest). The
+ * line number information is constant unless a new class definition is
+ * installed using RedefineClasses."
+ *
+ * @return the line table
+ * @throws JdwpException
+ */
+ public native LineTable getLineTable()
+ throws JdwpException;
+
+ /**
+ * "Returns variable information for the method. The variable table
+ * includes arguments and locals declared within the method. For instance
+ * methods, the "this" reference is included in the table. Also, synthetic
+ * variables may be present."
+ *
+ * @return the variable table
+ * @throws JdwpException
+ */
+ public native VariableTable getVariableTable()
+ throws JdwpException;
+
+ /**
+ * Returns a string representation of this method (not
+ * required but nice for debugging).
+ */
+ public String toString()
+ {
+ return getDeclaringClass().getName() + "." + getName();
+ }
+
+ /**
+ * Writes the method's ID to the output stream
+ *
+ * @param ostream the output stream to which to write
+ * @throws IOException for any errors writing to the stream
+ * @see gnu.classpath.jdwp.id.JdwpId#write
+ */
+ public void writeId(DataOutputStream ostream)
+ throws IOException
+ {
+ ostream.writeLong(getId());
+ }
+
+ /**
+ * Returns a VMMethod from the ID in the byte buffer
+ *
+ * @param klass the method's declaring class
+ * @param bb a ByteBuffer containing the method's ID
+ * @throws JdwpException for any errors creating the method
+ * @throws IOException for any errors reading from the buffer
+ */
+ public static VMMethod readId(Class klass, ByteBuffer bb)
+ throws JdwpException, IOException
+ {
+ return VMVirtualMachine.getClassMethod(klass, bb.getLong());
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof VMMethod)
+ {
+ VMMethod m = (VMMethod) obj;
+ return (getId() == m.getId());
+ }
+
+ return false;
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java
new file mode 100644
index 000000000..1f85a4a18
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java
@@ -0,0 +1,425 @@
+/* VMVirtualMachine.java -- A reference implementation of a JDWP virtual
+ machine
+
+ Copyright (C) 2005, 2006, 2007 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath.jdwp;
+
+import gnu.classpath.jdwp.event.EventRequest;
+import gnu.classpath.jdwp.exception.InvalidMethodException;
+import gnu.classpath.jdwp.exception.JdwpException;
+import gnu.classpath.jdwp.util.MethodResult;
+import gnu.classpath.jdwp.util.MonitorInfo;
+import gnu.classpath.jdwp.value.Value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * A virtual machine according to JDWP.
+ *
+ * @author Keith Seitz <keiths@redhat.com>
+ */
+public class VMVirtualMachine
+{
+ // VM Capabilities
+ public static final boolean canWatchFieldModification = false;
+ public static final boolean canWatchFieldAccess = false;
+ public static final boolean canGetBytecodes = false;
+ public static final boolean canGetSyntheticAttribute = false;
+ public static final boolean canGetOwnedMonitorInfo = false;
+ public static final boolean canGetCurrentContendedMonitor = false;
+ public static final boolean canGetMonitorInfo = false;
+ public static final boolean canRedefineClasses = false;
+ public static final boolean canAddMethod = false;
+ public static final boolean canUnrestrictedlyRedefineClasses = false;
+ public static final boolean canPopFrames = false;
+ public static final boolean canUseInstanceFilters = false;
+ public static final boolean canGetSourceDebugExtension = false;
+ public static final boolean canRequestVMDeathEvent = false;
+ public static final boolean canSetDefaultStratum = false;
+
+ /**
+ * Suspend a thread
+ *
+ * @param thread the thread to suspend
+ */
+ public static native void suspendThread(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Suspend all threads
+ */
+ public static void suspendAllThreads()
+ throws JdwpException
+ {
+ // Our JDWP thread group -- don't suspend any of those threads
+ Thread current = Thread.currentThread ();
+ ThreadGroup jdwpGroup = Jdwp.getDefault().getJdwpThreadGroup();
+
+ // Find the root ThreadGroup
+ ThreadGroup group = jdwpGroup;
+ ThreadGroup parent = group.getParent ();
+ while (parent != null)
+ {
+ group = parent;
+ parent = group.getParent ();
+ }
+
+ // Get all the threads in the system
+ int num = group.activeCount ();
+ Thread[] threads = new Thread[num];
+ group.enumerate (threads);
+
+ for (int i = 0; i < num; ++i)
+ {
+ Thread t = threads[i];
+ if (t != null)
+ {
+ if (t.getThreadGroup () == jdwpGroup || t == current)
+ {
+ // Don't suspend the current thread or any JDWP thread
+ continue;
+ }
+ else
+ suspendThread (t);
+ }
+ }
+
+ // Now suspend the current thread
+ if (current.getThreadGroup() != jdwpGroup)
+ suspendThread (current);
+ }
+
+ /**
+ * Resume a thread. A thread must be resumed as many times
+ * as it has been suspended.
+ *
+ * @param thread the thread to resume
+ */
+ public static native void resumeThread(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Resume all threads. This simply decrements the thread's
+ * suspend count. It can not be used to force the application
+ * to run.
+ */
+ public static void resumeAllThreads()
+ throws JdwpException
+ {
+ // Our JDWP thread group -- don't resume
+ Thread current = Thread.currentThread ();
+ ThreadGroup jdwpGroup = current.getThreadGroup ();
+
+ // Find the root ThreadGroup
+ ThreadGroup group = jdwpGroup;
+ ThreadGroup parent = group.getParent ();
+ while (parent != null)
+ {
+ group = parent;
+ parent = group.getParent ();
+ }
+
+ // Get all the threads in the system
+ int num = group.activeCount ();
+ Thread[] threads = new Thread[num];
+ group.enumerate (threads);
+
+ for (int i = 0; i < num; ++i)
+ {
+ Thread t = threads[i];
+ if (t != null)
+ {
+ if (t.getThreadGroup () == jdwpGroup || t == current)
+ {
+ // Don't resume the current thread or any JDWP thread
+ continue;
+ }
+ else
+ resumeThread (t);
+ }
+ }
+ }
+
+ /**
+ * Get the suspend count for a give thread
+ *
+ * @param thread the thread whose suspend count is desired
+ * @return the number of times the thread has been suspended
+ */
+ public static native int getSuspendCount(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Returns a Collection of all classes loaded in the VM
+ */
+ public static native Collection getAllLoadedClasses()
+ throws JdwpException;
+
+ /**
+ * Returns the status of the given class
+ *
+ * @param clazz the class whose status is desired
+ * @return a flag containing the class's status
+ * @see JdwpConstants.ClassStatus
+ */
+ public static native int getClassStatus(Class clazz)
+ throws JdwpException;
+
+ /**
+ * Returns all of the methods defined in the given class. This
+ * includes all methods, constructors, and class initializers.
+ *
+ * @param klass the class whose methods are desired
+ * @return an array of virtual machine methods
+ */
+ public static native VMMethod[] getAllClassMethods(Class klass)
+ { return null; }
+
+ /**
+ * A factory method for getting valid virtual machine methods
+ * which may be passed to/from the debugger.
+ *
+ * @param klass the class in which the method is defined
+ * @param id the ID of the desired method
+ * @return the desired internal representation of the method
+ * @throws InvalidMethodException if the method is not defined
+ * in the class
+ * @throws JdwpException for any other error
+ */
+ public static native VMMethod getClassMethod(Class klass, long id)
+ { return null; }
+
+ /**
+ * Returns the thread's call stack
+ *
+ * @param thread thread for which to get call stack
+ * @param start index of first frame to return
+ * @param length number of frames to return (-1 for all frames)
+ * @return a list of frames
+ */
+ public static native ArrayList getFrames(Thread thread, int start,
+ int length)
+ throws JdwpException;
+
+ /**
+ * Returns the frame for a given thread with the frame ID in
+ * the buffer
+ *
+ * I don't like this.
+ *
+ * @param thread the frame's thread
+ * @param bb buffer containing the frame's ID
+ * @return the desired frame
+ */
+ public static native VMFrame getFrame(Thread thread, long frameID)
+ throws JdwpException;
+
+ /**
+ * Returns the number of frames in the thread's stack
+ *
+ * @param thread the thread for which to get a frame count
+ * @return the number of frames in the thread's stack
+ */
+ public static native int getFrameCount(Thread thread)
+ throws JdwpException;
+
+
+ /**
+ * Returns the status of a thread
+ *
+ * @param thread the thread for which to get status
+ * @return integer status of the thread
+ * @see JdwpConstants.ThreadStatus
+ */
+ public static native int getThreadStatus(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Returns a list of all classes which this class loader has been
+ * requested to load
+ *
+ * @param cl the class loader
+ * @return a list of all visible classes
+ */
+ public static native ArrayList getLoadRequests(ClassLoader cl)
+ throws JdwpException;
+
+ /**
+ * Executes a method in the virtual machine. The thread must already
+ * be suspended by a previous event. When the method invocation is
+ * complete, the thread (or all threads if INVOKE_SINGLE_THREADED is
+ * not set in options) must be suspended before this method returns.
+ *
+ * @param obj instance in which to invoke method (null for static)
+ * @param thread the thread in which to invoke the method
+ * @param clazz the class in which the method is defined
+ * @param method the method to invoke
+ * @param values arguments to pass to method
+ * @param options invocation options
+ * @return a result object containing the results of the invocation
+ */
+ public static native MethodResult executeMethod (Object obj, Thread thread,
+ Class clazz, VMMethod method,
+ Value[] values,
+ int options)
+ throws JdwpException;
+
+ /**
+ * "Returns the name of source file in which a reference type was declared"
+ *
+ * @param clazz the class for which to return a source file
+ * @return a string containing the source file name; "no path information
+ * for the file is included"
+ */
+ public static native String getSourceFile(Class clazz)
+ throws JdwpException;
+
+ /**
+ * Register a request from the debugger
+ *
+ * Virtual machines have two options. Either do nothing and allow
+ * the event manager to take care of the request (useful for broadcast-type
+ * events like class prepare/load/unload, thread start/end, etc.)
+ * or do some internal work to set up the event notification (useful for
+ * execution-related events like breakpoints, single-stepping, etc.).
+ */
+ public static native void registerEvent(EventRequest request)
+ throws JdwpException;
+
+ /**
+ * Unregisters the given request
+ *
+ * @param request the request to unregister
+ */
+ public static native void unregisterEvent(EventRequest request)
+ throws JdwpException;
+
+
+ /**
+ * Clear all events of the given kind
+ *
+ * @param kind the type of events to clear
+ */
+ public static native void clearEvents(byte kind)
+ throws JdwpException;
+
+ /**
+ * Redefines the given types. VM must support canRedefineClasses
+ * capability (may also require canAddMethod and/or
+ * canUnrestrictedlyRedefineClasses capabilities)
+ *
+ * @param types the classes to redefine
+ * @param bytecodes the new bytecode definitions for the classes
+ */
+ public static native void redefineClasses(Class[] types, byte[][] bytecodes)
+ throws JdwpException;
+
+ /**
+ * Sets the default stratum. VM must support the
+ * canSetDefaultStratum capability.
+ *
+ * @param stratum the new default stratum or empty string to
+ * use the reference default
+ */
+ public static native void setDefaultStratum(String stratum)
+ throws JdwpException;
+
+ /**
+ * Returns the source debug extension. VM must support the
+ * canGetSourceDebugExtension capability.
+ *
+ * @param klass the class for which to return information
+ * @returns the source debug extension
+ */
+ public static native String getSourceDebugExtension(Class klass)
+ throws JdwpException;
+
+ /**
+ * Returns the bytecode for the given method. VM must support the
+ * canGetBytecodes capability.
+ *
+ * @param method the method for which to get bytecodes
+ * @returns the bytecodes
+ */
+ public static native byte[] getBytecodes(VMMethod method)
+ throws JdwpException;
+
+ /**
+ * Returns monitor information about an object. VM must support
+ * the canGetMonitorInformation capability.
+ *
+ * @param obj the object
+ * @returns monitor information (owner, entry count, waiters)
+ */
+ public static native MonitorInfo getMonitorInfo(Object obj)
+ throws JdwpException;
+
+ /**
+ * Returns a list of owned monitors. VM must support the
+ * canGetOwnedMonitorInfo capability.
+ *
+ * @param thread a thread
+ * @returns the list of monitors owned by this thread
+ */
+ public static native Object[] getOwnedMonitors(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Returns the current contended monitor for a thread. VM must
+ * support canGetCurrentContendedMonitor capability.
+ *
+ * @param thread the thread
+ * @returns the contended monitor
+ */
+ public static native Object getCurrentContendedMonitor(Thread thread)
+ throws JdwpException;
+
+ /**
+ * Pop all frames up to and including the given frame. VM must
+ * support canPopFrames capability. It is the responsibility
+ * of the VM to check if the thread is suspended. If it is not,
+ * the VM should throw ThreadNotSuspendedException.
+ *
+ * @param thread the thread
+ * @param frame the frame ID
+ */
+ public static native void popFrames(Thread thread, long frameId);
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/VMCPStringBuilder.java b/libjava/classpath/vm/reference/gnu/java/lang/VMCPStringBuilder.java
new file mode 100644
index 000000000..c3a3784f3
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/VMCPStringBuilder.java
@@ -0,0 +1,112 @@
+/* VMCPStringBuilder.java -- Growable strings without locking or copying
+ Copyright (C) 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * This class provides VM support for CPStringBuilder
+ * by allowing the package-private constructor
+ * of java.lang.String to be invoked. The default
+ * implementation uses reflection. VMs may replace
+ * this class with a more efficient version.
+ */
+final class VMCPStringBuilder
+{
+
+ /**
+ * The package-private constructor for String objects without copying.
+ */
+ private static final Constructor cons;
+
+ static
+ {
+ try
+ {
+ cons = String.class.getDeclaredConstructor(new Class[] { char[].class,
+ Integer.TYPE,
+ Integer.TYPE,
+ Boolean.TYPE });
+ cons.setAccessible(true);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw (Error)
+ new InternalError("Could not get no-copy String constructor").initCause(e);
+ }
+ }
+
+ /**
+ * Convert this <code>StringBuilder</code> to a <code>String</code>. The
+ * String is composed of the characters currently in this StringBuilder. Note
+ * that the result is not a copy, so the builder will allocate a new array
+ * if a further write operation is attempted.
+ *
+ * @param value the buffered characters.
+ * @param startIndex the index at which to start taking characters from the buffer.
+ * @param count the number of characters used in the buffer.
+ * @return the characters in this StringBuilder
+ */
+ public static String toString(char[] value, int startIndex, int count)
+ {
+ try
+ {
+ return (String)
+ cons.newInstance(new Object[] { value, Integer.valueOf(startIndex),
+ Integer.valueOf(count),
+ Boolean.valueOf(true) });
+ }
+ catch (InstantiationException e)
+ {
+ throw (Error)
+ new InternalError("Could not instantiate no-copy String constructor").initCause(e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw (Error)
+ new InternalError("Could not access no-copy String constructor").initCause(e);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw (Error)
+ new InternalError("Error calling no-copy String constructor").initCause(e);
+ }
+ }
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/VMInstrumentationImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/VMInstrumentationImpl.java
new file mode 100644
index 000000000..5501f0f7f
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/VMInstrumentationImpl.java
@@ -0,0 +1,108 @@
+/* VMInstrumentationImpl.java -- interface for the GNU implementation
+ of InstrumentationImpl
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.lang;
+
+import java.lang.instrument.ClassDefinition;
+import java.lang.instrument.Instrumentation;
+
+/**
+ * @author Nicolas Geoffray (nicolas.geoffray@menlina.com)
+ * @since 1.5
+ */
+final class VMInstrumentationImpl
+{
+
+ /**
+ * Returns if the current JVM supports class redefinition
+ *
+ * @return true if the current JVM supports class redefinition
+ */
+ static native boolean isRedefineClassesSupported();
+
+ /**
+ * Redefines classes given as parameters. The method has to call
+ * the callTransformers from InstrumentationImpl
+ *
+ * @param inst an instrumentation object
+ * @param definitions an array of bytecode<->class correspondance
+ *
+ * @throws ClassNotFoundException if a class cannot be found
+ * @throws UnmodifiableClassException if a class cannot be modified
+ * @throws UnsupportedOperationException if the JVM does not support
+ * redefinition or the redefinition made unsupported changes
+ * @throws ClassFormatError if a class file is not valid
+ * @throws NoClassDefFoundError if a class name is not equal to the name
+ * in the class file specified
+ * @throws UnsupportedClassVersionError if the class file version numbers
+ * are unsupported
+ * @throws ClassCircularityError if circularity occured with the new
+ * classes
+ * @throws LinkageError if a linkage error occurs
+ */
+ static native void redefineClasses(Instrumentation inst,
+ ClassDefinition[] definitions);
+
+ /**
+ * Get all the classes loaded by the JVM.
+ *
+ * @return an array containing all the classes loaded by the JVM. The array
+ * is empty if no class is loaded.
+ */
+ static native Class[] getAllLoadedClasses();
+
+ /**
+ * Get all the classes loaded by a given class loader
+ *
+ * @param loader the loader
+ *
+ * @return an array containing all the classes loaded by the given loader.
+ * The array is empty if no class was loaded by the loader.
+ */
+ static native Class[] getInitiatedClasses(ClassLoader loader);
+
+ /**
+ * Get the size of an object. The object is not null
+ *
+ * @param objectToSize the object
+ * @return the size of the object
+ */
+ static native long getObjectSize(Object objectToSize);
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMClassLoadingMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMClassLoadingMXBeanImpl.java
new file mode 100644
index 000000000..ea4989741
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMClassLoadingMXBeanImpl.java
@@ -0,0 +1,89 @@
+/* VMClassLoadingMXBeanImpl.java - VM impl. of a class loading bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+/**
+ * Provides access to information about the class loading
+ * behaviour of the current invocation of the virtual
+ * machine. Instances of this bean are obtained by calling
+ * {@link ManagementFactory#getClassLoadingMXBean()}.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMClassLoadingMXBeanImpl
+{
+
+ /**
+ * Returns the number of classes currently loaded by
+ * the virtual machine.
+ *
+ * @return the number of loaded classes.
+ */
+ static native int getLoadedClassCount();
+
+ /**
+ * Returns the number of classes that have been unloaded
+ * by the virtual machine since it was started.
+ *
+ * @return the number of unloaded classes.
+ */
+ static native long getUnloadedClassCount();
+
+ /**
+ * Returns true if the virtual machine will emit additional
+ * information when classes are loaded and unloaded. The
+ * format of the output is left up to the virtual machine.
+ *
+ * @return true if verbose class loading output is on.
+ */
+ static native boolean isVerbose();
+
+ /**
+ * Turns on or off the emission of additional information
+ * when classes are loaded and unloaded. The format of the
+ * output is left up to the virtual machine. This method
+ * may be called by multiple threads concurrently, but there
+ * is only one global setting of verbosity that is affected.
+ *
+ * @param verbose the new setting for verbose class loading
+ * output.
+ */
+ static native void setVerbose(boolean verbose);
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMCompilationMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMCompilationMXBeanImpl.java
new file mode 100644
index 000000000..019af0ca4
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMCompilationMXBeanImpl.java
@@ -0,0 +1,66 @@
+/* VMCompilationMXBeanImpl.java - VM implementation of a compilation bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+/**
+ * Provides access to information about the JIT
+ * compiler of the virtual machine, if one exists.
+ * Instances of this bean are obtained by calling
+ * {@link ManagementFactory#getCompilationMXBean()},
+ * if this is the case.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMCompilationMXBeanImpl
+{
+
+ /**
+ * Returns the number of milliseconds the JIT
+ * compiler has spent compiling Java bytecode
+ * to native machine code. This is only called
+ * if a JIT compiler exists and the
+ * gnu.java.lang.management.CompilationTimeSupport
+ * property has been set.
+ *
+ * @return the number of milliseconds spent
+ * compiling.
+ */
+ static native long getTotalCompilationTime();
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java
new file mode 100644
index 000000000..00861bc21
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java
@@ -0,0 +1,80 @@
+/* VMGarbageCollectorMXBeanImpl.java - VM interface for a GC bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+/**
+ * Provides access to information about the garbage collectors
+ * of the virtual machine. Garbage collectors are responsible
+ * for removing unreferenced objects from memory. A garbage
+ * collector is a type of memory manager, so this interface
+ * is combined with that of generic memory managers. An instance
+ * of this bean for each garbage collector is obtained by calling
+ * {@link ManagementFactory#getGarbageCollectorMXBeans()}.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMGarbageCollectorMXBeanImpl
+{
+
+ /**
+ * Returns the number of collections the garbage collector
+ * represented by this bean has made. -1 is returned if the
+ * collection count is undefined.
+ *
+ * @param name the name of the garbage collector.
+ * @return the number of collections made, or -1 if this is
+ * undefined.
+ */
+ static native long getCollectionCount(String name);
+
+ /**
+ * Returns the accumulated number of milliseconds this garbage
+ * collector has spent freeing the memory used by unreferenced
+ * objects. -1 is returned if the collection time is undefined.
+ * Note that the accumulated time may not change, even when the
+ * collection count increases, if the time taken is sufficiently
+ * short; this depends on the resolution of the timer used.
+ *
+ * @param name the name of the garbage collector.
+ * @return the accumulated number of milliseconds spent collecting,
+ * or -1 if this is undefined.
+ */
+ static native long getCollectionTime(String name);
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryMXBeanImpl.java
new file mode 100644
index 000000000..7f69bdfb7
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryMXBeanImpl.java
@@ -0,0 +1,156 @@
+/* VMMemoryMXBeanImpl.java - VM impl. of a memory bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryType;
+import java.lang.management.MemoryUsage;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Provides access to information about the memory
+ * management of the current invocation of the virtual
+ * machine. Instances of this bean are obtained by calling
+ * {@link ManagementFactory#getMemoryMXBean()}.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMMemoryMXBeanImpl
+{
+
+ /**
+ * Returns an instance of {@link java.lang.management.MemoryUsage}
+ * with appropriate initial, used, committed and maximum values
+ * for the heap. By default, this uses the methods of
+ * {@link java.lang.Runtime} to provide some of the values.
+ *
+ * @return an {@link java.lang.management.MemoryUsage} instance
+ * for the heap.
+ */
+ static MemoryUsage getHeapMemoryUsage()
+ {
+ return getUsage(MemoryType.HEAP);
+ }
+
+ /**
+ * Returns an instance of {@link java.lang.management.MemoryUsage}
+ * with appropriate initial, used, committed and maximum values
+ * for non-heap memory.
+ *
+ * @return an {@link java.lang.management.MemoryUsage} instance
+ * for non-heap memory.
+ */
+ static MemoryUsage getNonHeapMemoryUsage()
+ {
+ return getUsage(MemoryType.NON_HEAP);
+ }
+
+ /**
+ * Returns the number of objects ready to be garbage collected.
+ *
+ * @return the number of finalizable objects.
+ */
+ static native int getObjectPendingFinalizationCount();
+
+ /**
+ * Returns true if the virtual machine will emit additional
+ * information when memory is allocated and deallocated. The
+ * format of the output is left up to the virtual machine.
+ *
+ * @return true if verbose memory usage output is on.
+ */
+ static native boolean isVerbose();
+
+ /**
+ * Turns on or off the emission of additional information
+ * when memory is allocated and deallocated. The format of the
+ * output is left up to the virtual machine. This method
+ * may be called by multiple threads concurrently, but there
+ * is only one global setting of verbosity that is affected.
+ *
+ * @param verbose the new setting for verbose memory usage
+ * output.
+ */
+ static native void setVerbose(boolean verbose);
+
+ /**
+ * Totals the memory usage from all the pools that match
+ * the given type.
+ *
+ * @param type the type of memory pools to accumulate
+ * (heap or non-heap).
+ * @return the memory usage overall.
+ */
+ private static MemoryUsage getUsage(MemoryType type) {
+ long init = 0, committed = 0, used = 0, max = 0;
+ Iterator pools =
+ ManagementFactory.getMemoryPoolMXBeans().iterator();
+ while (pools.hasNext())
+ {
+ MemoryPoolMXBean pool = (MemoryPoolMXBean) pools.next();
+ if (pool.getType() == type)
+ {
+ MemoryUsage usage = pool.getUsage();
+ if (init != -1)
+ {
+ long poolInit = usage.getInit();
+ if (poolInit == -1)
+ init = -1;
+ else
+ init += poolInit;
+ }
+ committed += usage.getCommitted();
+ used += usage.getUsed();
+ if (max != -1)
+ {
+ long poolMax = usage.getMax();
+ if (poolMax == -1)
+ max = -1;
+ else
+ max += poolMax;
+ }
+ }
+ }
+ return new MemoryUsage(init, used, committed, max);
+ }
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java
new file mode 100644
index 000000000..477329f0a
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java
@@ -0,0 +1,95 @@
+/* VMMemoryManagerMXBeanImpl.java - VM interface for a memory manager bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Provides access to information about the memory managers
+ * of the virtual machine. An instance of this bean for each
+ * memory manager is obtained by calling
+ * {@link ManagementFactory#getMemoryManagerMXBeans()}.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMMemoryManagerMXBeanImpl
+{
+
+ /**
+ * Returns an array containing the names of the memory pools
+ * this memory manager manages.
+ *
+ * @param name the name of the memory manager.
+ * @return an array containing the name of each memory pool
+ * this manager is responsible for.
+ */
+ static String[] getMemoryPoolNames(String name)
+ {
+ List managedPools = new ArrayList();
+ Iterator beans = ManagementFactory.getMemoryPoolMXBeans().iterator();
+ while (beans.hasNext())
+ {
+ MemoryPoolMXBean bean = (MemoryPoolMXBean) beans.next();
+ String[] managers = bean.getMemoryManagerNames();
+ for (int a = 0; a < managers.length; ++a)
+ if (managers[a].equals(name))
+ {
+ managedPools.add(bean.getName());
+ break;
+ }
+ }
+ return (String[]) managedPools.toArray(new String[managedPools.size()]);
+ }
+
+ /**
+ * Returns true if this memory manager is still valid. A memory
+ * manager becomes invalid when it is removed by the virtual machine
+ * and no longer used.
+ *
+ * @param name the name of the memory manager.
+ * @return true if this memory manager is valid.
+ */
+ static native boolean isValid(String name);
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java
new file mode 100644
index 000000000..36cd2586a
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java
@@ -0,0 +1,195 @@
+/* MemoryPoolMXBeanImpl.java - VM interface for memory pool beans
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import java.lang.management.MemoryUsage;
+
+/**
+ * Provides access to information on the memory resources or
+ * pools used by the current invocation of the virtual machine.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMMemoryPoolMXBeanImpl
+{
+
+ /**
+ * Returns memory usage statistics for the specified pool
+ * just after a best-effort attempt to free memory. This
+ * is valid only for certain garbage collectors.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return a {@link java.lang.management.MemoryUsage} object
+ * containing the statistics or <code>null</code>
+ * if this pool does not support such statistics.
+ */
+ static native MemoryUsage getCollectionUsage(String name);
+
+ /**
+ * Returns the collection usage threshold for the specified pool.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.CollectionUsageThresholdSupport</code>,
+ * is defined). The value is initially zero.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return the collection usage threshold.
+ */
+ static native long getCollectionUsageThreshold(String name);
+
+ /**
+ * Returns the number of times the collection usage threshold
+ * has been met or exceeded by the specified pool.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.CollectionUsageThresholdSupport</code>,
+ * is defined).
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return the collection usage threshold count.
+ */
+ static native long getCollectionUsageThresholdCount(String name);
+
+ /**
+ * Returns an array of names of memory managers which manage
+ * the specified pool.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return a list of memory managers for the pool.
+ */
+ static native String[] getMemoryManagerNames(String name);
+
+ /**
+ * Returns the peak usage level of the specified pool.
+ * This is only called if the pool is valid.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return a {@link java.lang.management.MemoryUsage} object
+ * containing the statistics.
+ */
+ static native MemoryUsage getPeakUsage(String name);
+
+ /**
+ * Returns the type of memory used by the specified pool.
+ * The value must be either "HEAP" or "NON_HEAP".
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return the type of the given pool.
+ */
+ static native String getType(String name);
+
+ /**
+ * Returns the current usage level of the specified pool.
+ * This is only called if the pool is valid.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return a {@link java.lang.management.MemoryUsage} object
+ * containing the statistics.
+ */
+ static native MemoryUsage getUsage(String name);
+
+ /**
+ * Returns the usage threshold for the specified pool.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.UsageThresholdSupport</code>,
+ * is defined). The value is initially defined by the
+ * virtual machine.
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return the usage threshold.
+ */
+ static native long getUsageThreshold(String name);
+
+ /**
+ * Returns the number of times the usage threshold
+ * has been met or exceeded by the specified pool.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.UsageThresholdSupport</code>,
+ * is defined).
+ *
+ * @param name the name of the pool to obtain statistics on.
+ * @return the usage threshold count.
+ */
+ static native long getUsageThresholdCount(String name);
+
+ /**
+ * Returns true if the specified pool is still valid i.e.
+ * it is still in use by the virtual machine.
+ *
+ * @param name the name of the pool to check the validity of.
+ * @return true if the pool is valid.
+ */
+ static native boolean isValid(String name);
+
+ /**
+ * Resets the peak usage level to the current usage level for
+ * the specified pool.
+ *
+ * @param name the name of the pool to reset the peak usage of.
+ */
+ static native void resetPeakUsage(String name);
+
+ /**
+ * Sets the collection usage threshold for the specified
+ * pool to the supplied value.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.CollectionUsageThresholdSupport</code>,
+ * is defined).
+ *
+ * @param name the name of the pool to set the threshold of.
+ * @param threshold the new threshold level.
+ */
+ static native void setCollectionUsageThreshold(String name, long threshold);
+
+ /**
+ * Sets the usage threshold for the specified pool to the supplied value.
+ * This is only called if this functionality is supported
+ * by the virtual machine (i.e. the appropriate property,
+ * <code>gnu.java.lang.management.UsageThresholdSupport</code>,
+ * is defined).
+ *
+ * @param name the name of the pool to set the threshold of.
+ * @param threshold the new threshold level.
+ */
+ static native void setUsageThreshold(String name, long threshold);
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java
new file mode 100644
index 000000000..20b3f9ed2
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java
@@ -0,0 +1,68 @@
+/* VMOperatingSystemMXBeanImpl.java - VM implementation of an OS bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import gnu.classpath.Configuration;
+
+/**
+ * Provides access to information about the operating system.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.6
+ */
+final class VMOperatingSystemMXBeanImpl
+{
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalangmanagement");
+ }
+ }
+
+ /**
+ * Returns the system load average from the last
+ * minute.
+ *
+ * @return the system load average from the last
+ * minute.
+ */
+ static native double getSystemLoadAverage();
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMRuntimeMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMRuntimeMXBeanImpl.java
new file mode 100644
index 000000000..32a866046
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMRuntimeMXBeanImpl.java
@@ -0,0 +1,89 @@
+/* VMRuntimeMXBeanImpl.java - VM implementation of an runtime bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import gnu.classpath.SystemProperties;
+
+/**
+ * Provides access to information about the virtual machine.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMRuntimeMXBeanImpl
+{
+
+ /**
+ * Returns the command-line arguments supplied
+ * to the virtual machine, excluding those supplied
+ * to <code>main()</code>.
+ *
+ * @return the command-line arguments.
+ */
+ static native String[] getInputArguments();
+
+ /**
+ * Returns a developer-chosen name for the virtual
+ * machine, which may differ over different running
+ * instances of the same virtual machine binary.
+ * For example, this may include the particular
+ * process identifier used by this instance or
+ * the host name of the machine on which it is
+ * running. The intention is that this name refers
+ * to the precise entity that the other data supplied
+ * by the bean refers to, rather than the VM in general.
+ *
+ * @return the custom name of the VM.
+ */
+ static String getName()
+ {
+ return SystemProperties.getProperty("java.vm.name") + " " +
+ SystemProperties.getProperty("java.vm.version");
+ }
+
+ /**
+ * The time in milliseconds at which the virtual
+ * machine was started. This method is only executed
+ * once (for efficency), as the value is not expected
+ * to change.
+ *
+ * @return the VM start time.
+ */
+ static native long getStartTime();
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java b/libjava/classpath/vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java
new file mode 100644
index 000000000..33448d9d5
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java
@@ -0,0 +1,236 @@
+/* VMThreadMXBeanImpl.java - VM impl. of a thread bean
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import java.lang.management.ThreadInfo;
+
+/**
+ * Provides access to information about the threads
+ * of the virtual machine. An instance of this bean is
+ * obtained by calling
+ * {@link ManagementFactory#getThreadMXBean()}.
+ * See {@link java.lang.management.ThreadMXBean} for
+ * full documentation.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMThreadMXBeanImpl
+{
+
+ /**
+ * Cache of how many threads were found.
+ */
+ private static int filled;
+
+ /**
+ * Returns the ids of cycles of deadlocked threads, occurring
+ * due to monitor ownership or ownable synchronizer ownership.
+ * This will only be called if ownable synchronizer monitoring
+ * is supported.
+ *
+ * @return the ids of the deadlocked threads.
+ */
+ static native long[] findDeadlockedThreads();
+
+ /**
+ * Returns the ids of cycles of deadlocked threads, occurring
+ * due to monitor ownership.
+ *
+ * @return the ids of the deadlocked threads.
+ */
+ static native long[] findMonitorDeadlockedThreads();
+
+ /* This is the same as in Thread.getAllStackTraces() */
+ static Thread[] getAllThreads()
+ {
+ ThreadGroup group = Thread.currentThread().getThreadGroup();
+ while (group.getParent() != null)
+ group = group.getParent();
+ int arraySize = group.activeCount();
+ Thread[] threadList = new Thread[arraySize];
+ filled = group.enumerate(threadList);
+ while (filled == arraySize)
+ {
+ arraySize *= 2;
+ threadList = new Thread[arraySize];
+ filled = group.enumerate(threadList);
+ }
+ return threadList;
+ }
+
+ /**
+ * Returns the id of all live threads at the time of execution.
+ *
+ * @return the live thread ids.
+ */
+ static long[] getAllThreadIds()
+ {
+ Thread[] threadList = getAllThreads();
+ long[] ids = new long[filled];
+ for (int a = 0; a < filled; ++a)
+ ids[a] = threadList[a].getId();
+ return ids;
+ }
+
+ /**
+ * Returns the number of nanoseconds of CPU time
+ * the current thread has used in total. This is
+ * only called if this feature is enabled and
+ * supported.
+ *
+ * @return the nanoseconds of CPU time used by
+ * the current thread.
+ */
+ static native long getCurrentThreadCpuTime();
+
+ /**
+ * Returns the number of nanoseconds of user time
+ * the current thread has used in total. This is
+ * only called if this feature is enabled and
+ * supported.
+ *
+ * @return the nanoseconds of user time used by
+ * the current thread.
+ */
+ static native long getCurrentThreadUserTime();
+
+ /**
+ * Returns the number of live daemon threads.
+ *
+ * @return the number of live daemon threads.
+ */
+ static int getDaemonThreadCount()
+ {
+ Thread[] threadList = getAllThreads();
+ int daemonCount = 0;
+ for (int a = 0; a < filled; ++a)
+ {
+ if (threadList[a].isDaemon())
+ ++daemonCount;
+ }
+ return daemonCount;
+ }
+
+ /**
+ * Fill out the given {@link ThreadInfo} object
+ * with ownable synchronizer usage information.
+ * This is only called if ownable synchronizer
+ * usage monitoring is supported.
+ *
+ * @param info the {@link ThreadInfo} object to modify.
+ */
+ static native void getLockInfo(ThreadInfo info);
+
+ /**
+ * Fill out the given {@link ThreadInfo} object
+ * with monitor usage information. This is only
+ * called if monitor usage monitoring is supported.
+ *
+ * @param info the {@link ThreadInfo} object to modify.
+ */
+ static native void getMonitorInfo(ThreadInfo info);
+
+ /**
+ * Returns the current peak number of live threads.
+ *
+ * @return the peak number of live threads.
+ */
+ static native int getPeakThreadCount();
+
+ /**
+ * Returns the number of live threads.
+ *
+ * @return the number of live threads.
+ */
+ static int getThreadCount()
+ {
+ getAllThreads();
+ return filled;
+ }
+
+ /**
+ * Returns the number of nanoseconds of CPU time
+ * the specified thread has used in total. This is
+ * only called if this feature is enabled and
+ * supported.
+ *
+ * @param id the thread to obtain statistics on.
+ * @return the nanoseconds of CPU time used by
+ * the thread.
+ */
+ static native long getThreadCpuTime(long id);
+
+ /**
+ * Returns the {@link java.lang.management.ThreadInfo}
+ * which corresponds to the specified id.
+ *
+ * @param id the id of the thread.
+ * @param maxDepth the depth of the stack trace.
+ * @return the corresponding <code>ThreadInfo</code>.
+ */
+ static native ThreadInfo getThreadInfoForId(long id, int maxDepth);
+
+ /**
+ * Returns the number of nanoseconds of user time
+ * the specified thread has used in total. This is
+ * only called if this feature is enabled and
+ * supported.
+ *
+ * @param id the thread to obtain statistics on.
+ * @return the nanoseconds of user time used by
+ * the thread.
+ */
+ static native long getThreadUserTime(long id);
+
+ /**
+ * Returns the total number of threads that have
+ * been started over the lifetime of the virtual
+ * machine.
+ *
+ * @return the total number of threads started.
+ */
+ static native long getTotalStartedThreadCount();
+
+ /**
+ * Resets the peak thread count to the current
+ * number of live threads.
+ */
+ static native void resetPeakThreadCount();
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/net/VMPlainDatagramSocketImpl.java b/libjava/classpath/vm/reference/gnu/java/net/VMPlainDatagramSocketImpl.java
new file mode 100644
index 000000000..da0f893cf
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/net/VMPlainDatagramSocketImpl.java
@@ -0,0 +1,260 @@
+/* PlainDatagramSocketImpl.java -- VM interface for DatagramSocket impl
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.net;
+
+import gnu.classpath.Configuration;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+
+/**
+ * The VM interface for {@link gnu.java.net.PlainDatagramSocketImpl}.
+ *
+ * @author Ingo Proetel (proetel@aicas.com)
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public final class VMPlainDatagramSocketImpl
+{
+ /**
+ * Option id for the IP_TTL (time to live) value.
+ */
+ static final int IP_TTL = 0x1E61; // 7777
+
+
+ // Static initializer to load native library
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javanet");
+ }
+ }
+
+ /**
+ * Binds this socket to a particular port and interface
+ *
+ * @param socket the socket object
+ * @param port the port to bind to
+ * @param addr the address to bind to
+ *
+ * @throws SocketException If an error occurs
+ */
+ static native void bind(PlainDatagramSocketImpl socket, int port,
+ InetAddress addr)
+ throws SocketException;
+
+ /**
+ * Creates a new datagram socket.
+ *
+ * @param socket the socket object
+ *
+ * @throws SocketException If an error occurs
+ */
+ static native void create(PlainDatagramSocketImpl socket)
+ throws SocketException;
+
+ /**
+ * Connects to the remote address and port specified as arguments.
+ *
+ * @param socket the socket object
+ * @param addr the remote address to connect to
+ * @param port the remote port to connect to
+ *
+ * @throws SocketException If an error occurs
+ */
+ static native void connect(PlainDatagramSocketImpl socket, InetAddress addr,
+ int port)
+ throws SocketException;
+
+ /**
+ * Sends a packet of data to a remote host.
+ *
+ * @param socket the socket object
+ * @param packet the packet to send
+ *
+ * @throws IOException If an error occurs
+ */
+ static void send(PlainDatagramSocketImpl socket, DatagramPacket packet)
+ throws IOException
+ {
+ nativeSendTo(socket, packet.getAddress(), packet.getPort(),
+ packet.getData(), packet.getOffset(), packet.getLength());
+ }
+
+
+ /**
+ * Sends a packet of data to a remote host.
+ *
+ * @param socket the socket object
+ * @param addr the address to send to
+ * @param port the port to send to
+ * @param buf the buffer to send
+ * @param offset the offset of the data in the buffer to send
+ * @param len the length of the data to send
+ *
+ * @throws IOException If an error occurs
+ */
+ private static native void nativeSendTo(PlainDatagramSocketImpl socket,
+ InetAddress addr, int port,
+ byte[] buf, int offset, int len)
+ throws IOException;
+
+ /**
+ * Receives a UDP packet from the network
+ *
+ * @param socket the socket object
+ * @param packet the packet to fill in with the data received
+ *
+ * @throws IOException IOException If an error occurs
+ */
+ static void receive(PlainDatagramSocketImpl socket, DatagramPacket packet)
+ throws IOException
+ {
+ byte[] receiveFromAddress = new byte[4];
+ int[] receiveFromPort = new int[1];
+ int[] receivedLength = new int[1];
+
+ nativeReceive(socket, packet.getData(), packet.getOffset(),
+ packet.getLength(),
+ receiveFromAddress, receiveFromPort, receivedLength);
+
+ packet.setAddress(InetAddress.getByAddress(receiveFromAddress));
+ packet.setPort(receiveFromPort[0]);
+ packet.setLength(receivedLength[0]);
+ }
+
+ private static native void nativeReceive(PlainDatagramSocketImpl socket,
+ byte[] buf, int offset, int len,
+ byte[] receiveFromAddress,
+ int[] receiveFromPort,
+ int[] receivedLength)
+ throws IOException;
+
+ /**
+ * Sets the value of an option on the socket
+ *
+ * @param socket the socket object
+ * @param optionId the identifier of the option to set
+ * @param value the value of the option to set
+ *
+ * @exception SocketException If an error occurs
+ */
+ static native void setOption(PlainDatagramSocketImpl socket, int optionId,
+ Object value)
+ throws SocketException;
+
+ /**
+ * Retrieves the value of an option on the socket.
+ *
+ * @param socket the socket object
+ * @param optionId the identifier of the option to retrieve
+ *
+ * @return the value of the option
+ *
+ * @throws SocketException if an error occurs
+ */
+ static native Object getOption(PlainDatagramSocketImpl socket, int optionId)
+ throws SocketException;
+
+ /**
+ * Closes the socket.
+ *
+ * @param socket the socket object
+ */
+ static native void close(PlainDatagramSocketImpl socket);
+
+ /**
+ * Joins a multicast group
+ *
+ * @param addr The group to join
+ *
+ * @exception IOException If an error occurs
+ */
+ static native void join(PlainDatagramSocketImpl socket, InetAddress addr)
+ throws IOException;
+
+ /**
+ * Leaves a multicast group
+ *
+ * @param addr The group to leave
+ *
+ * @exception IOException If an error occurs
+ */
+ static native void leave(PlainDatagramSocketImpl socket, InetAddress addr)
+ throws IOException;
+
+ /**
+ * Joins a multicast group.
+ *
+ * @param socket the socket object
+ * @param address the socket address
+ * @param netIf the network interface
+ *
+ * @throws IOException if I/O errors occur
+ */
+ static void joinGroup(PlainDatagramSocketImpl socket, SocketAddress address,
+ NetworkInterface netIf)
+ throws IOException
+ {
+ throw new InternalError
+ ("PlainDatagramSocketImpl::joinGroup is not implemented");
+ }
+
+ /**
+ * Leaves a multicast group.
+ *
+ * @param socket the socket object
+ * @param address the socket address
+ * @param netIf the network interface
+ *
+ * @throws IOException if I/O errors occur
+ */
+ static void leaveGroup(PlainDatagramSocketImpl socket, SocketAddress address,
+ NetworkInterface netIf)
+ throws IOException
+ {
+ throw new InternalError
+ ("PlainDatagramSocketImpl::leaveGroup is not implemented");
+ }
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/net/VMPlainSocketImpl.java b/libjava/classpath/vm/reference/gnu/java/net/VMPlainSocketImpl.java
new file mode 100644
index 000000000..c72e6a5eb
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/net/VMPlainSocketImpl.java
@@ -0,0 +1,511 @@
+/* VMPlainSocketImpl.java -- VM interface for default socket implementation
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.net;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.SocketOptions;
+
+import gnu.classpath.Configuration;
+import gnu.java.nio.VMChannel;
+
+/**
+ * The VM interface for {@link gnu.java.net.PlainSocketImpl}.
+ *
+ * @author Ingo Proetel (proetel@aicas.com)
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public final class VMPlainSocketImpl
+{
+ /** Option id for time to live
+ */
+ private static final int CP_IP_TTL = 0x1E61;
+
+ private final State nfd;
+
+ /**
+ * Static initializer to load native library.
+ */
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javanet");
+ }
+ }
+
+ public VMPlainSocketImpl()
+ {
+ // XXX consider adding security check here.
+ nfd = new State();
+ }
+
+ public VMPlainSocketImpl(VMChannel channel) throws IOException
+ {
+ this();
+ nfd.setChannelFD(channel.getState());
+ }
+
+ public State getState()
+ {
+ return nfd;
+ }
+
+ /** This method exists to hide the CP_IP_TTL value from
+ * higher levels.
+ *
+ * Always think of JNode ... :)
+ */
+ public void setTimeToLive(int ttl)
+ throws SocketException
+ {
+ try
+ {
+ setOption(nfd.getNativeFD(), CP_IP_TTL, ttl);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+
+ public int getTimeToLive()
+ throws SocketException
+ {
+ try
+ {
+ return getOption(nfd.getNativeFD(), CP_IP_TTL);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+
+ public void setOption(int optionId, Object optionValue)
+ throws SocketException
+ {
+ int value;
+ if (optionValue instanceof Integer)
+ value = ((Integer) optionValue).intValue();
+ else if (optionValue instanceof Boolean)
+ // Switching off the linger behavior is done by setting
+ // the value to -1. This is how the Java API interprets
+ // it.
+ value = ((Boolean) optionValue).booleanValue()
+ ? 1
+ : (optionId == SocketOptions.SO_LINGER)
+ ? -1
+ : 0;
+ else
+ throw new IllegalArgumentException("option value type "
+ + optionValue.getClass().getName());
+
+ try
+ {
+ setOption(nfd.getNativeFD(), optionId, value);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+
+ private static native void setOption(int fd, int id, int value)
+ throws SocketException;
+
+ public void setMulticastInterface(int optionId, InetAddress addr)
+ throws SocketException
+ {
+ try
+ {
+ if (addr instanceof Inet4Address)
+ setMulticastInterface(nfd.getNativeFD(), optionId, (Inet4Address) addr);
+ else if (addr instanceof Inet6Address)
+ {
+ NetworkInterface iface = NetworkInterface.getByInetAddress(addr);
+ setMulticastInterface6(nfd.getNativeFD(), optionId, iface.getName());
+ }
+ else
+ throw new SocketException("Unknown address format: " + addr);
+ }
+ catch (SocketException se)
+ {
+ throw se;
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+
+ private static native void setMulticastInterface(int fd,
+ int optionId,
+ Inet4Address addr);
+
+ private static native void setMulticastInterface6(int fd,
+ int optionId,
+ String ifName);
+
+ /**
+ * Get a socket option. This implementation is only required to support
+ * socket options that are boolean values, which include:
+ *
+ * SocketOptions.IP_MULTICAST_LOOP
+ * SocketOptions.SO_BROADCAST
+ * SocketOptions.SO_KEEPALIVE
+ * SocketOptions.SO_OOBINLINE
+ * SocketOptions.SO_REUSEADDR
+ * SocketOptions.TCP_NODELAY
+ *
+ * and socket options that are integer values, which include:
+ *
+ * SocketOptions.IP_TOS
+ * SocketOptions.SO_LINGER
+ * SocketOptions.SO_RCVBUF
+ * SocketOptions.SO_SNDBUF
+ * SocketOptions.SO_TIMEOUT
+ *
+ * @param optionId The option ID to fetch.
+ * @return A {@link Boolean} or {@link Integer} containing the socket
+ * option.
+ * @throws SocketException
+ */
+ public Object getOption(int optionId) throws SocketException
+ {
+ int value;
+ try
+ {
+ value = getOption(nfd.getNativeFD(), optionId);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+
+ switch (optionId)
+ {
+ case SocketOptions.IP_MULTICAST_LOOP:
+ case SocketOptions.SO_BROADCAST:
+ case SocketOptions.SO_KEEPALIVE:
+ case SocketOptions.SO_OOBINLINE:
+ case SocketOptions.SO_REUSEADDR:
+ case SocketOptions.TCP_NODELAY:
+ return Boolean.valueOf(value != 0);
+
+ case SocketOptions.IP_TOS:
+ case SocketOptions.SO_LINGER:
+ case SocketOptions.SO_RCVBUF:
+ case SocketOptions.SO_SNDBUF:
+ case SocketOptions.SO_TIMEOUT:
+ return new Integer(value);
+
+ default:
+ throw new SocketException("getting option " + optionId +
+ " not supported here");
+ }
+ }
+
+ private static native int getOption(int fd, int id) throws SocketException;
+
+ /**
+ * Returns an Inet4Address or Inet6Address instance belonging to the
+ * interface which is set as the multicast interface.
+ *
+ * The optionId is provided to make it possible that the native
+ * implementation may do something different depending on whether
+ * the value is SocketOptions.IP_MULTICAST_IF or
+ * SocketOptions.IP_MULTICAST_IF2.
+ */
+ public InetAddress getMulticastInterface(int optionId)
+ throws SocketException
+ {
+ try
+ {
+ return getMulticastInterface(nfd.getNativeFD(), optionId);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+
+ private static native InetAddress getMulticastInterface(int fd,
+ int optionId);
+
+ /**
+ * Binds this socket to the given local address and port.
+ *
+ * @param address The address to bind to; the InetAddress is either
+ * an IPv4 or IPv6 address.
+ * @throws IOException If binding fails; for example, if the port
+ * in the given InetSocketAddress is privileged, and the current
+ * process has insufficient privileges.
+ */
+ public void bind(InetSocketAddress address) throws IOException
+ {
+ InetAddress addr = address.getAddress();
+ if (addr instanceof Inet4Address)
+ {
+ bind (nfd.getNativeFD(), addr.getAddress(), address.getPort());
+ }
+ else if (addr instanceof Inet6Address)
+ bind6 (nfd.getNativeFD(), addr.getAddress(), address.getPort());
+ else
+ throw new SocketException ("unsupported address type");
+ }
+
+ /**
+ * Native bind function for IPv4 addresses. The addr array must be
+ * exactly four bytes long.
+ *
+ * VMs without native support need not implement this.
+ *
+ * @param fd The native file descriptor integer.
+ * @param addr The IPv4 address, in network byte order.
+ * @param port The port to bind to.
+ * @throws IOException
+ */
+ private static native void bind(int fd, byte[] addr, int port)
+ throws IOException;
+
+ /**
+ * Native bind function for IPv6 addresses. The addr array must be
+ * exactly sixteen bytes long.
+ *
+ * VMs without native support need not implement this.
+ *
+ * @param fd The native file descriptor integer.
+ * @param addr The IPv6 address, in network byte order.
+ * @param port The port to bind to.
+ * @throws IOException
+ */
+ private static native void bind6(int fd, byte[] addr, int port)
+ throws IOException;
+
+ /**
+ * Listen on this socket for incoming connections.
+ *
+ * @param backlog The backlog of connections.
+ * @throws IOException If listening fails.
+ * @see gnu.java.nio.VMChannel#accept()
+ */
+ public void listen(int backlog) throws IOException
+ {
+ listen(nfd.getNativeFD(), backlog);
+ }
+
+ /**
+ * Native listen function. VMs without native support need not implement
+ * this.
+ *
+ * @param fd The file descriptor integer.
+ * @param backlog The listen backlog size.
+ * @throws IOException
+ */
+ private static native void listen(int fd, int backlog) throws IOException;
+
+ public void join(InetAddress group) throws IOException
+ {
+ if (group instanceof Inet4Address)
+ join(nfd.getNativeFD(), group.getAddress());
+ else if (group instanceof Inet6Address)
+ join6(nfd.getNativeFD(), group.getAddress());
+ else
+ throw new IllegalArgumentException("unknown address type");
+ }
+
+ private static native void join(int fd, byte[] addr) throws IOException;
+
+ private static native void join6(int fd, byte[] addr) throws IOException;
+
+ public void leave(InetAddress group) throws IOException
+ {
+ if (group instanceof Inet4Address)
+ leave(nfd.getNativeFD(), group.getAddress());
+ else if (group instanceof Inet6Address)
+ leave6(nfd.getNativeFD(), group.getAddress());
+ else
+ throw new IllegalArgumentException("unknown address type");
+ }
+
+ private static native void leave(int fd, byte[] addr) throws IOException;
+
+ private static native void leave6(int fd, byte[] addr) throws IOException;
+
+ public void joinGroup(InetSocketAddress addr, NetworkInterface netif)
+ throws IOException
+ {
+ InetAddress address = addr.getAddress();
+
+ if (address instanceof Inet4Address)
+ joinGroup(nfd.getNativeFD(), address.getAddress(),
+ netif != null ? netif.getName() : null);
+ else if (address instanceof Inet6Address)
+ joinGroup6(nfd.getNativeFD(), address.getAddress(),
+ netif != null ? netif.getName() : null);
+ else
+ throw new IllegalArgumentException("unknown address type");
+ }
+
+ private static native void joinGroup(int fd, byte[] addr, String ifname)
+ throws IOException;
+
+ private static native void joinGroup6(int fd, byte[] addr, String ifname)
+ throws IOException;
+
+ public void leaveGroup(InetSocketAddress addr, NetworkInterface netif)
+ throws IOException
+ {
+ InetAddress address = addr.getAddress();
+ if (address instanceof Inet4Address)
+ leaveGroup(nfd.getNativeFD(), address.getAddress(),
+ netif != null ? netif.getName() : null);
+ else if (address instanceof Inet6Address)
+ leaveGroup6(nfd.getNativeFD(), address.getAddress(),
+ netif != null ? netif.getName() : null);
+ else
+ throw new IllegalArgumentException("unknown address type");
+ }
+
+ private static native void leaveGroup(int fd, byte[] addr, String ifname)
+ throws IOException;
+
+ private static native void leaveGroup6(int fd, byte[] addr, String ifname)
+ throws IOException;
+
+
+ public void shutdownInput() throws IOException
+ {
+ shutdownInput(nfd.getNativeFD());
+ }
+
+ private static native void shutdownInput(int native_fd) throws IOException;
+
+ public void shutdownOutput() throws IOException
+ {
+ shutdownOutput(nfd.getNativeFD());
+ }
+
+ private static native void shutdownOutput(int native_fd) throws IOException;
+
+ public void sendUrgentData(int data) throws IOException
+ {
+ sendUrgentData(nfd.getNativeFD(), data);
+ }
+
+ private static native void sendUrgentData(int natfive_fd, int data) throws IOException;
+
+ public void close() throws IOException
+ {
+ nfd.close();
+ }
+
+ // Inner classes.
+
+ /**
+ * Our wrapper for the native file descriptor. In this implementation,
+ * it is a simple wrapper around {@link VMChannel.State}, to simplify
+ * management of the native state.
+ */
+ public final class State
+ {
+ private VMChannel.State channelFd;
+
+ State()
+ {
+ channelFd = null;
+ }
+
+ public boolean isValid()
+ {
+ if (channelFd != null)
+ return channelFd.isValid();
+ return false;
+ }
+
+ public int getNativeFD() throws IOException
+ {
+ return channelFd.getNativeFD();
+ }
+
+ public void setChannelFD(final VMChannel.State nfd) throws IOException
+ {
+ if (this.channelFd != null && this.channelFd.isValid())
+ throw new IOException("file descriptor already initialized");
+ this.channelFd = nfd;
+ }
+
+ public void close() throws IOException
+ {
+ if (channelFd == null)
+ throw new IOException("invalid file descriptor");
+ channelFd.close();
+ }
+
+ protected void finalize() throws Throwable
+ {
+ try
+ {
+ if (isValid())
+ close();
+ }
+ finally
+ {
+ super.finalize();
+ }
+ }
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/nio/VMChannel.java b/libjava/classpath/vm/reference/gnu/java/nio/VMChannel.java
new file mode 100644
index 000000000..4494ff13c
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/nio/VMChannel.java
@@ -0,0 +1,749 @@
+/* VMChannel.java -- Native interface suppling channel operations.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.nio;
+
+import gnu.classpath.Configuration;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+
+/**
+ * Native interface to support configuring of channel to run in a non-blocking
+ * manner and support scatter/gather io operations.
+ *
+ * @author Michael Barker <mike@middlesoft.co.uk>
+ *
+ */
+public final class VMChannel
+{
+ /**
+ * Our reference implementation uses an integer to store the native
+ * file descriptor. Implementations without such support
+ */
+ private final State nfd;
+
+ private Kind kind;
+
+ public VMChannel()
+ {
+ // XXX consider adding security check here, so only Classpath
+ // code may create instances.
+ this.nfd = new State();
+ kind = Kind.OTHER;
+ }
+
+ /**
+ * This constructor is used by the POSIX reference implementation;
+ * other virtual machines need not support it.
+ *
+ * <strong>Important:</strong> do not call this in library code that is
+ * not specific to Classpath's reference implementation.
+ *
+ * @param native_fd The native file descriptor integer.
+ * @throws IOException
+ */
+ VMChannel(final int native_fd) throws IOException
+ {
+ this();
+ this.nfd.setNativeFD(native_fd);
+ }
+
+ public State getState()
+ {
+ return nfd;
+ }
+
+ static
+ {
+ // load the shared library needed for native methods.
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary ("javanio");
+ }
+ initIDs();
+ }
+
+ public static VMChannel getStdin() throws IOException
+ {
+ return new VMChannel(stdin_fd());
+ }
+
+ public static VMChannel getStdout() throws IOException
+ {
+ return new VMChannel(stdout_fd());
+ }
+
+ public static VMChannel getStderr() throws IOException
+ {
+ return new VMChannel(stderr_fd());
+ }
+
+ private static native int stdin_fd();
+ private static native int stdout_fd();
+ private static native int stderr_fd();
+
+ /**
+ * Set the file descriptor to have the required blocking
+ * setting.
+ *
+ * @param blocking The blocking flag to set.
+ */
+ public void setBlocking(boolean blocking) throws IOException
+ {
+ setBlocking(nfd.getNativeFD(), blocking);
+ }
+
+ private static native void setBlocking(int fd, boolean blocking)
+ throws IOException;
+
+ public int available() throws IOException
+ {
+ return available(nfd.getNativeFD());
+ }
+
+ private static native int available(int native_fd) throws IOException;
+
+ /**
+ * Reads a byte buffer directly using the supplied file descriptor.
+ *
+ * @param dst Direct Byte Buffer to read to.
+ * @return Number of bytes read.
+ * @throws IOException If an error occurs or dst is not a direct buffers.
+ */
+ public int read(ByteBuffer dst)
+ throws IOException
+ {
+ return read(nfd.getNativeFD(), dst);
+ }
+
+ private static native int read(int fd, ByteBuffer dst) throws IOException;
+
+ /**
+ * Read a single byte.
+ *
+ * @return The byte read, or -1 on end of file.
+ * @throws IOException
+ */
+ public int read() throws IOException
+ {
+ return read(nfd.getNativeFD());
+ }
+
+ private static native int read(int fd) throws IOException;
+
+ /**
+ * Reads into byte buffers directly using the supplied file descriptor.
+ * Assumes that the buffer list contains DirectBuffers. Will perform a
+ * scattering read.
+ *
+ * @param dsts An array direct byte buffers.
+ * @param offset Index of the first buffer to read to.
+ * @param length The number of buffers to read to.
+ * @return Number of bytes read.
+ * @throws IOException If an error occurs or the dsts are not direct buffers.
+ */
+ public long readScattering(ByteBuffer[] dsts, int offset, int length)
+ throws IOException
+ {
+ if (offset + length > dsts.length)
+ throw new IndexOutOfBoundsException("offset + length > dsts.length");
+
+ return readScattering(nfd.getNativeFD(), dsts, offset, length);
+ }
+
+ private static native long readScattering(int fd, ByteBuffer[] dsts,
+ int offset, int length)
+ throws IOException;
+
+ /**
+ * Receive a datagram on this channel, returning the host address
+ * that sent the datagram.
+ *
+ * @param dst Where to store the datagram.
+ * @return The host address that sent the datagram.
+ * @throws IOException
+ */
+ public SocketAddress receive(ByteBuffer dst) throws IOException
+ {
+ if (kind != Kind.SOCK_DGRAM)
+ throw new SocketException("not a datagram socket");
+ ByteBuffer hostPort = ByteBuffer.allocateDirect(18);
+ int hostlen = receive(nfd.getNativeFD(), dst, hostPort);
+ if (hostlen == 0)
+ return null;
+ if (hostlen == 4) // IPv4
+ {
+ byte[] addr = new byte[4];
+ hostPort.get(addr);
+ int port = hostPort.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet4Address.getByAddress(addr), port);
+ }
+ if (hostlen == 16) // IPv6
+ {
+ byte[] addr = new byte[16];
+ hostPort.get(addr);
+ int port = hostPort.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet6Address.getByAddress(addr), port);
+ }
+
+ throw new SocketException("host address received with invalid length: "
+ + hostlen);
+ }
+
+ private static native int receive (int fd, ByteBuffer dst, ByteBuffer address)
+ throws IOException;
+
+ /**
+ * Writes from a direct byte bufer using the supplied file descriptor.
+ * Assumes the buffer is a DirectBuffer.
+ *
+ * @param src The source buffer.
+ * @return Number of bytes written.
+ * @throws IOException
+ */
+ public int write(ByteBuffer src) throws IOException
+ {
+ return write(nfd.getNativeFD(), src);
+ }
+
+ private native int write(int fd, ByteBuffer src) throws IOException;
+
+ /**
+ * Writes from byte buffers directly using the supplied file descriptor.
+ * Assumes the that buffer list constains DirectBuffers. Will perform
+ * as gathering write.
+ *
+ * @param srcs
+ * @param offset
+ * @param length
+ * @return Number of bytes written.
+ * @throws IOException
+ */
+ public long writeGathering(ByteBuffer[] srcs, int offset, int length)
+ throws IOException
+ {
+ if (offset + length > srcs.length)
+ throw new IndexOutOfBoundsException("offset + length > srcs.length");
+
+ // A gathering write is limited to 16 buffers; when writing, ensure
+ // that we have at least one buffer with something in it in the 16
+ // buffer window starting at offset.
+ while (!srcs[offset].hasRemaining() && offset < srcs.length)
+ offset++;
+
+ // There are no buffers with anything to write.
+ if (offset == srcs.length)
+ return 0;
+
+ // If we advanced `offset' so far that we don't have `length'
+ // buffers left, reset length to only the remaining buffers.
+ if (length > srcs.length - offset)
+ length = srcs.length - offset;
+
+ return writeGathering(nfd.getNativeFD(), srcs, offset, length);
+ }
+
+ private native long writeGathering(int fd, ByteBuffer[] srcs,
+ int offset, int length)
+ throws IOException;
+
+ /**
+ * Send a datagram to the given address.
+ *
+ * @param src The source buffer.
+ * @param dst The destination address.
+ * @return The number of bytes written.
+ * @throws IOException
+ */
+ public int send(ByteBuffer src, InetSocketAddress dst)
+ throws IOException
+ {
+ InetAddress addr = dst.getAddress();
+ if (addr == null)
+ throw new NullPointerException();
+ if (addr instanceof Inet4Address)
+ return send(nfd.getNativeFD(), src, addr.getAddress(), dst.getPort());
+ else if (addr instanceof Inet6Address)
+ return send6(nfd.getNativeFD(), src, addr.getAddress(), dst.getPort());
+ else
+ throw new SocketException("unrecognized inet address type");
+ }
+
+ // Send to an IPv4 address.
+ private static native int send(int fd, ByteBuffer src, byte[] addr, int port)
+ throws IOException;
+
+ // Send to an IPv6 address.
+ private static native int send6(int fd, ByteBuffer src, byte[] addr, int port)
+ throws IOException;
+
+ /**
+ * Write a single byte.
+ *
+ * @param b The byte to write.
+ * @throws IOException
+ */
+ public void write(int b) throws IOException
+ {
+ write(nfd.getNativeFD(), b);
+ }
+
+ private static native void write(int fd, int b) throws IOException;
+
+ private native static void initIDs();
+
+ // Network (socket) specific methods.
+
+ /**
+ * Create a new socket. This method will initialize the native file
+ * descriptor state of this instance.
+ *
+ * @param stream Whether or not to create a streaming socket, or a datagram
+ * socket.
+ * @throws IOException If creating a new socket fails, or if this
+ * channel already has its native descriptor initialized.
+ */
+ public void initSocket(boolean stream) throws IOException
+ {
+ if (nfd.isValid())
+ throw new IOException("native FD already initialized");
+ if (stream)
+ kind = Kind.SOCK_STREAM;
+ else
+ kind = Kind.SOCK_DGRAM;
+ nfd.setNativeFD(socket(stream));
+ }
+
+ /**
+ * Create a new socket, returning the native file descriptor.
+ *
+ * @param stream Set to true for streaming sockets; false for datagrams.
+ * @return The native file descriptor.
+ * @throws IOException If creating the socket fails.
+ */
+ private static native int socket(boolean stream) throws IOException;
+
+ /**
+ * Connect the underlying socket file descriptor to the remote host.
+ *
+ * @param saddr The address to connect to.
+ * @param timeout The connect timeout to use for blocking connects.
+ * @return True if the connection succeeded; false if the file descriptor
+ * is in non-blocking mode and the connection did not immediately
+ * succeed.
+ * @throws IOException If an error occurs while connecting.
+ */
+ public boolean connect(InetSocketAddress saddr, int timeout)
+ throws SocketException
+ {
+ int fd;
+
+ InetAddress addr = saddr.getAddress();
+
+ // Translates an IOException into a SocketException to conform
+ // to the throws clause.
+ try
+ {
+ fd = nfd.getNativeFD();
+ }
+ catch (IOException ioe)
+ {
+ throw new SocketException(ioe.getMessage());
+ }
+
+ if (addr instanceof Inet4Address)
+ return connect(fd, addr.getAddress(), saddr.getPort(),
+ timeout);
+ if (addr instanceof Inet6Address)
+ return connect6(fd, addr.getAddress(), saddr.getPort(),
+ timeout);
+ throw new SocketException("unsupported internet address");
+ }
+
+ private static native boolean connect(int fd, byte[] addr, int port, int timeout)
+ throws SocketException;
+
+ private static native boolean connect6(int fd, byte[] addr, int port, int timeout)
+ throws SocketException;
+
+ /**
+ * Disconnect this channel, if it is a datagram socket. Disconnecting
+ * a datagram channel will disassociate it from any address, so the
+ * socket will remain open, but can send and receive datagrams from
+ * any address.
+ *
+ * @throws IOException If disconnecting this channel fails, or if this
+ * channel is not a datagram channel.
+ */
+ public void disconnect() throws IOException
+ {
+ if (kind != Kind.SOCK_DGRAM)
+ throw new IOException("can only disconnect datagram channels");
+ disconnect(nfd.getNativeFD());
+ }
+
+ private static native void disconnect(int fd) throws IOException;
+
+ public InetSocketAddress getLocalAddress() throws IOException
+ {
+ if (!nfd.isValid())
+ return null;
+ ByteBuffer name = ByteBuffer.allocateDirect(18);
+ int namelen = getsockname(nfd.getNativeFD(), name);
+ if (namelen == 0) // not bound
+ return null; // XXX return some wildcard?
+ if (namelen == 4)
+ {
+ byte[] addr = new byte[4];
+ name.get(addr);
+ int port = name.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet4Address.getByAddress(addr), port);
+ }
+ if (namelen == 16)
+ {
+ byte[] addr = new byte[16];
+ name.get(addr);
+ int port = name.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet6Address.getByAddress(addr), port);
+ }
+ throw new SocketException("invalid address length");
+ }
+
+ private static native int getsockname(int fd, ByteBuffer name)
+ throws IOException;
+
+ /**
+ * Returns the socket address of the remote peer this channel is connected
+ * to, or null if this channel is not yet connected.
+ *
+ * @return The peer address.
+ * @throws IOException
+ */
+ public InetSocketAddress getPeerAddress() throws IOException
+ {
+ if (!nfd.isValid())
+ return null;
+ ByteBuffer name = ByteBuffer.allocateDirect(18);
+ int namelen = getpeername (nfd.getNativeFD(), name);
+ if (namelen == 0) // not connected yet
+ return null;
+ if (namelen == 4) // IPv4
+ {
+ byte[] addr = new byte[4];
+ name.get(addr);
+ int port = name.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet4Address.getByAddress(addr), port);
+ }
+ else if (namelen == 16) // IPv6
+ {
+ byte[] addr = new byte[16];
+ name.get(addr);
+ int port = name.getShort() & 0xFFFF;
+ return new InetSocketAddress(Inet6Address.getByAddress(addr), port);
+ }
+ throw new SocketException("invalid address length");
+ }
+
+ /*
+ * The format here is the peer address, followed by the port number.
+ * The returned value is the length of the peer address; thus, there
+ * will be LEN + 2 valid bytes put into NAME.
+ */
+ private static native int getpeername(int fd, ByteBuffer name)
+ throws IOException;
+
+ /**
+ * Accept an incoming connection, returning a new VMChannel, or null
+ * if the channel is nonblocking and no connection is pending.
+ *
+ * @return The accepted connection, or null.
+ * @throws IOException If an IO error occurs.
+ */
+ public VMChannel accept() throws IOException
+ {
+ int new_fd = accept(nfd.getNativeFD());
+ if (new_fd == -1) // non-blocking accept had no pending connection
+ return null;
+ return new VMChannel(new_fd);
+ }
+
+ private static native int accept(int native_fd) throws IOException;
+
+ // File-specific methods.
+
+ /**
+ * Open a file at PATH, initializing the native state to operate on
+ * that open file.
+ *
+ * @param path The absolute file path.
+ * @throws IOException If the file cannot be opened, or if this
+ * channel was previously initialized.
+ */
+ public void openFile(String path, int mode) throws IOException
+ {
+ if (nfd.isValid() || nfd.isClosed())
+ throw new IOException("can't reinitialize this channel");
+ int fd = open(path, mode);
+ nfd.setNativeFD(fd);
+ kind = Kind.FILE;
+ }
+
+ private static native int open(String path, int mode) throws IOException;
+
+ public long position() throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ return position(nfd.getNativeFD());
+ }
+
+ private static native long position(int fd) throws IOException;
+
+ public void seek(long pos) throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ seek(nfd.getNativeFD(), pos);
+ }
+
+ private static native void seek(int fd, long pos) throws IOException;
+
+ public void truncate(long length) throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ truncate(nfd.getNativeFD(), length);
+ }
+
+ private static native void truncate(int fd, long len) throws IOException;
+
+ public boolean lock(long pos, long len, boolean shared, boolean wait)
+ throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ return lock(nfd.getNativeFD(), pos, len, shared, wait);
+ }
+
+ private static native boolean lock(int fd, long pos, long len,
+ boolean shared, boolean wait)
+ throws IOException;
+
+ public void unlock(long pos, long len) throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ unlock(nfd.getNativeFD(), pos, len);
+ }
+
+ private static native void unlock(int fd, long pos, long len) throws IOException;
+
+ public long size() throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ return size(nfd.getNativeFD());
+ }
+
+ private static native long size(int fd) throws IOException;
+
+ public MappedByteBuffer map(char mode, long position, int size)
+ throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ return map(nfd.getNativeFD(), mode, position, size);
+ }
+
+ private static native MappedByteBuffer map(int fd, char mode,
+ long position, int size)
+ throws IOException;
+
+ public boolean flush(boolean metadata) throws IOException
+ {
+ if (kind != Kind.FILE)
+ throw new IOException("not a file");
+ return flush(nfd.getNativeFD(), metadata);
+ }
+
+ private static native boolean flush(int fd, boolean metadata) throws IOException;
+
+ // Close.
+
+ /**
+ * Close this socket. The socket is also automatically closed when this
+ * object is finalized.
+ *
+ * @throws IOException If closing the socket fails, or if this object has
+ * no open socket.
+ */
+ public void close() throws IOException
+ {
+ nfd.close();
+ }
+
+ static native void close(int native_fd) throws IOException;
+
+ /**
+ * <p>Provides a simple mean for the JNI code to find out whether the
+ * current thread was interrupted by a call to Thread.interrupt().</p>
+ *
+ * @return
+ */
+ static boolean isThreadInterrupted()
+ {
+ return Thread.currentThread().isInterrupted();
+ }
+
+ // Inner classes.
+
+ /**
+ * A wrapper for a native file descriptor integer. This tracks the state
+ * of an open file descriptor, and ensures that
+ *
+ * This class need not be fully supported by virtual machines; if a
+ * virtual machine does not use integer file descriptors, or does and
+ * wishes to hide that, then the methods of this class may be stubbed out.
+ *
+ * System-specific classes that depend on access to native file descriptor
+ * integers SHOULD declare this fact.
+ */
+ public final class State
+ {
+ private int native_fd;
+ private boolean valid;
+ private boolean closed;
+
+ State()
+ {
+ native_fd = -1;
+ valid = false;
+ closed = false;
+ }
+
+ public boolean isValid()
+ {
+ return valid;
+ }
+
+ public boolean isClosed()
+ {
+ return closed;
+ }
+
+ public int getNativeFD() throws IOException
+ {
+ if (!valid)
+ throw new IOException("invalid file descriptor");
+ return native_fd;
+ }
+
+ void setNativeFD(final int native_fd) throws IOException
+ {
+ if (valid)
+ throw new IOException("file descriptor already initialized");
+ this.native_fd = native_fd;
+ valid = true;
+ }
+
+ public void close() throws IOException
+ {
+ if (!valid)
+ throw new IOException("invalid file descriptor");
+ try
+ {
+ VMChannel.close(native_fd);
+ }
+ finally
+ {
+ valid = false;
+ closed = true;
+ }
+ }
+
+ public String toString()
+ {
+ if (closed)
+ return "<<closed>>";
+ if (!valid)
+ return "<<invalid>>";
+ return String.valueOf(native_fd);
+ }
+
+ protected void finalize() throws Throwable
+ {
+ try
+ {
+ if (valid)
+ close();
+ }
+ finally
+ {
+ super.finalize();
+ }
+ }
+ }
+
+ /**
+ * An enumeration of possible kinds of channel.
+ */
+ static class Kind // XXX enum
+ {
+ /** A streaming (TCP) socket. */
+ static final Kind SOCK_STREAM = new Kind();
+
+ /** A datagram (UDP) socket. */
+ static final Kind SOCK_DGRAM = new Kind();
+
+ /** A file. */
+ static final Kind FILE = new Kind();
+
+ /** Something else; not a socket or file. */
+ static final Kind OTHER = new Kind();
+
+ private Kind() { }
+ }
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java b/libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java
new file mode 100644
index 000000000..a36970452
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/nio/VMPipe.java
@@ -0,0 +1,80 @@
+/* VMPipe.java -- Reference implementation for VM hooks used by PipeImpl
+ Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.nio;
+
+import java.io.IOException;
+import gnu.classpath.Configuration;
+
+/**
+ * This class contains the native methods for gnu.java.nio.PipeImpl
+ * As such, it needs help from the VM.
+ *
+ * @author Patrik Reali
+ */
+final class VMPipe
+{
+
+ static
+ {
+ // load the shared library needed for native methods.
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary ("javanio");
+ }
+ }
+
+ /**
+ * Create a pipe, consisting of a readable VMChannel and a writable
+ * VMChannel. The readable channel is returned is the first element
+ * of the array, and the writable in the second.
+ *
+ * @return A pair of VMChannels; the first readable, the second
+ * writable.
+ * @throws IOException If the pipe cannot be created.
+ */
+ static VMChannel[] pipe() throws IOException
+ {
+ VMChannel[] pipe = new VMChannel[2];
+ int[] fds = pipe0();
+ pipe[0] = new VMChannel(fds[0]);
+ pipe[1] = new VMChannel(fds[1]);
+ return pipe;
+ }
+
+ private static native int[] pipe0() throws IOException;
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java b/libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java
new file mode 100644
index 000000000..4d37c2c1c
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/nio/VMSelector.java
@@ -0,0 +1,59 @@
+/* VMSelector.java --
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.nio;
+
+import gnu.classpath.Configuration;
+import java.io.IOException;
+
+public final class VMSelector
+{
+ static
+ {
+ // load the shared library needed for native methods.
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary ("javanio");
+ }
+ }
+
+ // A timeout value of 0 means block forever.
+ static native int select (int[] read, int[] write,
+ int[] except, long timeout)
+ throws IOException;
+
+}
diff --git a/libjava/classpath/vm/reference/gnu/java/security/jce/prng/VMSecureRandom.java b/libjava/classpath/vm/reference/gnu/java/security/jce/prng/VMSecureRandom.java
new file mode 100644
index 000000000..86faa097c
--- /dev/null
+++ b/libjava/classpath/vm/reference/gnu/java/security/jce/prng/VMSecureRandom.java
@@ -0,0 +1,129 @@
+/* VMSecureRandom.java -- random seed generator.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.security.jce.prng;
+
+/**
+ * VM-specific methods for generating real (or almost real) random
+ * seeds. VM implementors should write a version of this class that
+ * reads random bytes from some system source.
+ *
+ * <p>The default implementation of this class runs eight threads that
+ * increment counters in a tight loop, and XORs each counter to
+ * produce one byte of seed data. This is not very efficient, and is
+ * not guaranteed to be random (the thread scheduler is probably
+ * deterministic, after all). If possible, VM implementors should
+ * reimplement this class so it obtains a random seed from a system
+ * facility, such as a system entropy gathering device or hardware
+ * random number generator.
+ */
+final class VMSecureRandom
+{
+
+ /**
+ * Generate a random seed. Implementations are free to generate
+ * fewer random bytes than are requested, and leave the remaining
+ * bytes of the destination buffer as zeros. Implementations SHOULD,
+ * however, make a best-effort attempt to satisfy the request.
+ *
+ * @param buffer The destination buffer.
+ * @param offset The offset in the buffer to start putting bytes.
+ * @param length The number of random bytes to generate.
+ */
+ static int generateSeed(byte[] buffer, int offset, int length)
+ {
+ if (length < 0)
+ throw new IllegalArgumentException("length must be nonnegative");
+ if (offset < 0 || offset + length > buffer.length)
+ throw new IndexOutOfBoundsException();
+
+ Spinner[] spinners = new Spinner[8];
+ int n = 0x1;
+ for (int i = 0; i < spinners.length; i++)
+ {
+ spinners[i] = new Spinner((byte) n);
+ Thread t = new Thread(spinners[i]);
+ t.start();
+ n <<= 1;
+ }
+
+ // Wait until at least one spinner has started.
+ while (!(spinners[0].running || spinners[1].running || spinners[2].running
+ || spinners[3].running || spinners[4].running || spinners[5].running
+ || spinners[6].running || spinners[7].running))
+ {
+ Thread.yield();
+ }
+
+ for (int i = offset; i < length; i++)
+ {
+ buffer[i] = (byte) (spinners[0].value ^ spinners[1].value ^ spinners[2].value
+ ^ spinners[3].value ^ spinners[4].value ^ spinners[5].value
+ ^ spinners[6].value ^ spinners[7].value);
+ Thread.yield();
+ }
+
+ for (int i = 0; i < spinners.length; i++)
+ spinners[i].stop();
+
+ return length;
+ }
+
+ static class Spinner implements Runnable
+ {
+ volatile byte value;
+ volatile boolean running;
+
+ Spinner(final byte initial)
+ {
+ value = initial;
+ }
+
+ public void run()
+ {
+ running = true;
+ while (running)
+ value++;
+ }
+
+ private void stop()
+ {
+ running = false;
+ }
+ }
+}