summaryrefslogtreecommitdiff
path: root/libjava/gnu/gcj/runtime
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/gnu/gcj/runtime
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libjava/gnu/gcj/runtime')
-rw-r--r--libjava/gnu/gcj/runtime/BootClassLoader.h53
-rw-r--r--libjava/gnu/gcj/runtime/BootClassLoader.java138
-rw-r--r--libjava/gnu/gcj/runtime/ExtensionClassLoader.h40
-rw-r--r--libjava/gnu/gcj/runtime/ExtensionClassLoader.java40
-rw-r--r--libjava/gnu/gcj/runtime/FinalizerThread.h41
-rw-r--r--libjava/gnu/gcj/runtime/FinalizerThread.java32
-rw-r--r--libjava/gnu/gcj/runtime/HelperClassLoader$1.h38
-rw-r--r--libjava/gnu/gcj/runtime/HelperClassLoader.h35
-rw-r--r--libjava/gnu/gcj/runtime/HelperClassLoader.java72
-rw-r--r--libjava/gnu/gcj/runtime/JNIWeakRef.h32
-rw-r--r--libjava/gnu/gcj/runtime/JNIWeakRef.java24
-rw-r--r--libjava/gnu/gcj/runtime/NameFinder$Addr2Line.h39
-rw-r--r--libjava/gnu/gcj/runtime/NameFinder.h50
-rw-r--r--libjava/gnu/gcj/runtime/NameFinder.java341
-rw-r--r--libjava/gnu/gcj/runtime/PersistentByteMap$AccessMode.h49
-rw-r--r--libjava/gnu/gcj/runtime/PersistentByteMap$ByteWrapper.h42
-rw-r--r--libjava/gnu/gcj/runtime/PersistentByteMap$HashIterator.h44
-rw-r--r--libjava/gnu/gcj/runtime/PersistentByteMap$MapEntry.h40
-rw-r--r--libjava/gnu/gcj/runtime/PersistentByteMap.h115
-rw-r--r--libjava/gnu/gcj/runtime/PersistentByteMap.java619
-rw-r--r--libjava/gnu/gcj/runtime/SharedLibHelper.h76
-rw-r--r--libjava/gnu/gcj/runtime/SharedLibHelper.java224
-rw-r--r--libjava/gnu/gcj/runtime/SharedLibLoader.h47
-rw-r--r--libjava/gnu/gcj/runtime/SharedLibLoader.java79
-rw-r--r--libjava/gnu/gcj/runtime/StringBuffer.h54
-rw-r--r--libjava/gnu/gcj/runtime/StringBuffer.java199
-rw-r--r--libjava/gnu/gcj/runtime/SystemClassLoader.h40
-rw-r--r--libjava/gnu/gcj/runtime/SystemClassLoader.java113
-rw-r--r--libjava/gnu/gcj/runtime/natFinalizerThread.cc62
-rw-r--r--libjava/gnu/gcj/runtime/natSharedLibLoader.cc151
-rw-r--r--libjava/gnu/gcj/runtime/natStringBuffer.cc36
-rw-r--r--libjava/gnu/gcj/runtime/natSystemClassLoader.cc31
32 files changed, 2996 insertions, 0 deletions
diff --git a/libjava/gnu/gcj/runtime/BootClassLoader.h b/libjava/gnu/gcj/runtime/BootClassLoader.h
new file mode 100644
index 000000000..c1d398798
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/BootClassLoader.h
@@ -0,0 +1,53 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_BootClassLoader__
+#define __gnu_gcj_runtime_BootClassLoader__
+
+#pragma interface
+
+#include <gnu/gcj/runtime/HelperClassLoader.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class BootClassLoader;
+ }
+ }
+ }
+ namespace java
+ {
+ namespace net
+ {
+ class URL;
+ class URLClassLoader;
+ }
+ }
+}
+
+class gnu::gcj::runtime::BootClassLoader : public ::gnu::gcj::runtime::HelperClassLoader
+{
+
+public: // actually package-private
+ BootClassLoader(::java::lang::String *);
+public:
+ ::java::lang::Class * bootLoadClass(::java::lang::String *);
+private:
+ ::java::net::URLClassLoader * getBootURLLoader();
+public:
+ ::java::net::URL * bootGetResource(::java::lang::String *);
+ ::java::util::Enumeration * bootGetResources(::java::lang::String *);
+public: // actually package-private
+ static ::java::lang::Class * coreHandler;
+private:
+ jboolean __attribute__((aligned(__alignof__( ::gnu::gcj::runtime::HelperClassLoader)))) initialized;
+ ::java::net::URLClassLoader * bootURLLoader;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_BootClassLoader__
diff --git a/libjava/gnu/gcj/runtime/BootClassLoader.java b/libjava/gnu/gcj/runtime/BootClassLoader.java
new file mode 100644
index 000000000..40f3147b7
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/BootClassLoader.java
@@ -0,0 +1,138 @@
+/* Copyright (C) 2005, 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.runtime;
+
+import gnu.java.net.protocol.core.Handler;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * This is a helper for the bootstrap class loader. It is a
+ * URLClassLoader so that we can read a class path and re-use all the
+ * existing code for finding classes, extracting them from jars, etc.
+ * However, it is never called the way that an ordinary ClassLoader is
+ * called. For instance, loadClass() is never used.
+ */
+public final class BootClassLoader extends HelperClassLoader
+{
+ // This forces the core URL handler to be included in statically
+ // linked executables. The line that adds core:/ to the search
+ // path fails otherwise.
+ static Class coreHandler = gnu.java.net.protocol.core.Handler.class;
+
+ private boolean initialized;
+ private URLClassLoader bootURLLoader;
+
+ BootClassLoader(String libdir)
+ {
+ // The BootClassLoader is the top of the delegation chain. It does not
+ // have a parent.
+ super((ClassLoader) null);
+ addDirectoriesFromProperty("java.endorsed.dirs");
+ addDirectoriesFromProperty("gnu.gcj.runtime.endorsed.dirs");
+
+ try
+ {
+ // Add core:/ to the end so any resources compiled into this
+ // executable may be found.
+ addURL(new URL("core", "", -1, "/"));
+ }
+ catch (java.net.MalformedURLException x)
+ {
+ // This should never happen.
+ throw new RuntimeException(x);
+ }
+ }
+
+ public Class bootLoadClass(String name)
+ throws ClassNotFoundException
+ {
+ Class c = findLoadedClass(name);
+ if (c == null)
+ {
+ try
+ {
+ // We could hack URLClassLoader to make this more
+ // efficient, if it mattered.
+ c = findClass(name);
+ }
+ catch (ClassNotFoundException _)
+ {
+ c = null;
+ }
+ }
+ return c;
+ }
+
+ // Parse the boot classpath and create a URLClassLoader that loads
+ // resources from it. This is provided for the benefit of code that
+ // does things like
+ // ClassLoader.getResourceAsStream("java/lang/Object.class")
+ private synchronized URLClassLoader getBootURLLoader()
+ {
+ if (initialized)
+ return bootURLLoader;
+ initialized = true;
+
+ Vector<URL> urls = new Vector<URL>();
+ String bootClasspath = System.getProperty ("sun.boot.class.path");
+ StringTokenizer st =
+ new StringTokenizer(bootClasspath, File.pathSeparator);
+ while (st.hasMoreTokens())
+ {
+ try
+ {
+ urls.add(new File(st.nextToken()).toURL());
+ }
+ catch (java.net.MalformedURLException e)
+ {
+ }
+ }
+
+ if (urls.size() > 0)
+ bootURLLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]));
+ return bootURLLoader;
+ }
+
+ public URL bootGetResource(String name)
+ {
+ URL url = findResource(name);
+ if (url != null)
+ return url;
+
+ URLClassLoader loader = getBootURLLoader();
+ if (loader != null)
+ url = loader.findResource(name);
+
+ return url;
+ }
+
+ public Enumeration bootGetResources(String name) throws IOException
+ {
+ URLClassLoader loader = getBootURLLoader();
+ Enumeration[] e =
+ {
+ findResources(name),
+ (loader != null) ? loader.findResources(name) : null
+ };
+
+ Vector v = new Vector();
+ for (Enumeration en : e)
+ if (en != null)
+ while (en.hasMoreElements())
+ v.add(en.nextElement());
+
+ return v.elements();
+ }
+}
diff --git a/libjava/gnu/gcj/runtime/ExtensionClassLoader.h b/libjava/gnu/gcj/runtime/ExtensionClassLoader.h
new file mode 100644
index 000000000..ee17c2d84
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/ExtensionClassLoader.h
@@ -0,0 +1,40 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_ExtensionClassLoader__
+#define __gnu_gcj_runtime_ExtensionClassLoader__
+
+#pragma interface
+
+#include <gnu/gcj/runtime/HelperClassLoader.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class ExtensionClassLoader;
+ class SystemClassLoader;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::ExtensionClassLoader : public ::gnu::gcj::runtime::HelperClassLoader
+{
+
+ ExtensionClassLoader();
+ void init();
+public: // actually package-private
+ static void initialize();
+ static ::gnu::gcj::runtime::ExtensionClassLoader * instance;
+ static ::gnu::gcj::runtime::SystemClassLoader * system_instance;
+public:
+ static ::java::lang::Class class$;
+
+ friend class ::java::lang::ClassLoader;
+};
+
+#endif // __gnu_gcj_runtime_ExtensionClassLoader__
diff --git a/libjava/gnu/gcj/runtime/ExtensionClassLoader.java b/libjava/gnu/gcj/runtime/ExtensionClassLoader.java
new file mode 100644
index 000000000..690143a43
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/ExtensionClassLoader.java
@@ -0,0 +1,40 @@
+/* Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/* Author: Kresten Krab Thorup <krab@gnu.org> */
+
+package gnu.gcj.runtime;
+
+import java.net.URL;
+
+// The extension loader for libgcj. Class loader bootstrap is a bit
+// tricky, see prims.cc and SystemClassLoader for some details.
+public final class ExtensionClassLoader extends HelperClassLoader
+{
+ private ExtensionClassLoader ()
+ {
+ }
+
+ private void init()
+ {
+ addDirectoriesFromProperty("java.ext.dirs");
+ }
+
+ // This can be package-private because we only call it from native
+ // code during startup.
+ static void initialize ()
+ {
+ instance.init();
+ system_instance.init();
+ }
+
+ // The only ExtensionClassLoader that can exist.
+ static ExtensionClassLoader instance = new ExtensionClassLoader();
+ // The system class loader.
+ static SystemClassLoader system_instance = new SystemClassLoader(instance);
+}
diff --git a/libjava/gnu/gcj/runtime/FinalizerThread.h b/libjava/gnu/gcj/runtime/FinalizerThread.h
new file mode 100644
index 000000000..572f89d59
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/FinalizerThread.h
@@ -0,0 +1,41 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_FinalizerThread__
+#define __gnu_gcj_runtime_FinalizerThread__
+
+#pragma interface
+
+#include <java/lang/Thread.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class FinalizerThread;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::FinalizerThread : public ::java::lang::Thread
+{
+
+public:
+ FinalizerThread();
+private:
+ void init();
+public: // actually package-private
+ static void finalizerReady();
+public:
+ void run();
+private:
+ static jboolean finalizer_ready;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_FinalizerThread__
diff --git a/libjava/gnu/gcj/runtime/FinalizerThread.java b/libjava/gnu/gcj/runtime/FinalizerThread.java
new file mode 100644
index 000000000..c9a917cd2
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/FinalizerThread.java
@@ -0,0 +1,32 @@
+// FinalizerThread.java -- Thread in which finalizers are run.
+
+/* Copyright (C) 2001, 2004 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.runtime;
+
+/**
+ * @author Tom Tromey <tromey@redhat.com>
+ * @date October 3, 2001
+ */
+public final class FinalizerThread extends Thread
+{
+ private static boolean finalizer_ready;
+
+ public FinalizerThread ()
+ {
+ super ("LibgcjInternalFinalizerThread");
+ setDaemon (true);
+ finalizer_ready = false;
+ init();
+ }
+
+ private native void init();
+ static native void finalizerReady();
+ public native void run();
+}
diff --git a/libjava/gnu/gcj/runtime/HelperClassLoader$1.h b/libjava/gnu/gcj/runtime/HelperClassLoader$1.h
new file mode 100644
index 000000000..ee0447755
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/HelperClassLoader$1.h
@@ -0,0 +1,38 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_HelperClassLoader$1__
+#define __gnu_gcj_runtime_HelperClassLoader$1__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class HelperClassLoader;
+ class HelperClassLoader$1;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::HelperClassLoader$1 : public ::java::lang::Object
+{
+
+public: // actually package-private
+ HelperClassLoader$1(::gnu::gcj::runtime::HelperClassLoader *);
+public:
+ virtual jboolean accept(::java::io::File *, ::java::lang::String *);
+public: // actually package-private
+ ::gnu::gcj::runtime::HelperClassLoader * __attribute__((aligned(__alignof__( ::java::lang::Object)))) this$0;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_HelperClassLoader$1__
diff --git a/libjava/gnu/gcj/runtime/HelperClassLoader.h b/libjava/gnu/gcj/runtime/HelperClassLoader.h
new file mode 100644
index 000000000..30311d3f8
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/HelperClassLoader.h
@@ -0,0 +1,35 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_HelperClassLoader__
+#define __gnu_gcj_runtime_HelperClassLoader__
+
+#pragma interface
+
+#include <java/net/URLClassLoader.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class HelperClassLoader;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::HelperClassLoader : public ::java::net::URLClassLoader
+{
+
+public: // actually package-private
+ HelperClassLoader();
+ HelperClassLoader(::java::lang::ClassLoader *);
+ virtual void addDirectoriesFromProperty(::java::lang::String *);
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_HelperClassLoader__
diff --git a/libjava/gnu/gcj/runtime/HelperClassLoader.java b/libjava/gnu/gcj/runtime/HelperClassLoader.java
new file mode 100644
index 000000000..3b48da17c
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/HelperClassLoader.java
@@ -0,0 +1,72 @@
+/* Copyright (C) 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.runtime;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.StringTokenizer;
+
+/**
+ * This is a URLClassLoader that has an extra helper method for
+ * handling things like java.ext.dirs.
+ */
+class HelperClassLoader extends URLClassLoader
+{
+ HelperClassLoader()
+ {
+ super(new URL[0]);
+ }
+
+ HelperClassLoader(ClassLoader parent)
+ {
+ super(new URL[0], parent);
+ }
+
+ /**
+ * This is a helper method that adds all the jar and zip files from
+ * a given list of paths to this class loader. The paths are taken
+ * from a system property whose name is provided as an argument.
+ */
+ final void addDirectoriesFromProperty(String propName)
+ {
+ StringTokenizer st
+ = new StringTokenizer (System.getProperty (propName, ""),
+ File.pathSeparator);
+ try
+ {
+ while (st.hasMoreElements ())
+ {
+ String dirname = st.nextToken ();
+ File dir = new File (dirname);
+ if (dir.exists ())
+ {
+ if (! dirname.endsWith (File.separator))
+ dirname = dirname + File.separator;
+ String files[] = dir.list (new FilenameFilter ()
+ {
+ public boolean accept (File dir, String name)
+ {
+ return name.endsWith (".jar") || name.endsWith (".zip");
+ }
+ });
+ for (int i = files.length - 1; i >= 0; i--)
+ addURL(new URL("file", "", -1, dirname + files[i]));
+ }
+ }
+ }
+ catch (java.net.MalformedURLException x)
+ {
+ // This should never happen.
+ throw new RuntimeException(x);
+ }
+ }
+}
diff --git a/libjava/gnu/gcj/runtime/JNIWeakRef.h b/libjava/gnu/gcj/runtime/JNIWeakRef.h
new file mode 100644
index 000000000..e23a59f6d
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/JNIWeakRef.h
@@ -0,0 +1,32 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_JNIWeakRef__
+#define __gnu_gcj_runtime_JNIWeakRef__
+
+#pragma interface
+
+#include <java/lang/ref/WeakReference.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class JNIWeakRef;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::JNIWeakRef : public ::java::lang::ref::WeakReference
+{
+
+public:
+ JNIWeakRef(::java::lang::Object *);
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_JNIWeakRef__
diff --git a/libjava/gnu/gcj/runtime/JNIWeakRef.java b/libjava/gnu/gcj/runtime/JNIWeakRef.java
new file mode 100644
index 000000000..c0c76cdb6
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/JNIWeakRef.java
@@ -0,0 +1,24 @@
+// JNIWeakRef.java - Wrapper class for JNI-specific weak references.
+
+/* Copyright (C) 2001 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.runtime;
+
+import java.lang.ref.*;
+
+// This wrapper is used by the JNI implementation to keep track of
+// global weak references. Each such reference is wrapped in an
+// instance of this class, and automatically unwrapped when used.
+public final class JNIWeakRef extends WeakReference
+{
+ public JNIWeakRef (Object referent)
+ {
+ super (referent);
+ }
+}
diff --git a/libjava/gnu/gcj/runtime/NameFinder$Addr2Line.h b/libjava/gnu/gcj/runtime/NameFinder$Addr2Line.h
new file mode 100644
index 000000000..7d5b5a342
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/NameFinder$Addr2Line.h
@@ -0,0 +1,39 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_NameFinder$Addr2Line__
+#define __gnu_gcj_runtime_NameFinder$Addr2Line__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class NameFinder;
+ class NameFinder$Addr2Line;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::NameFinder$Addr2Line : public ::java::lang::Object
+{
+
+public: // actually package-private
+ NameFinder$Addr2Line(::gnu::gcj::runtime::NameFinder *, ::java::lang::String *);
+ virtual void close();
+ ::java::lang::Process * __attribute__((aligned(__alignof__( ::java::lang::Object)))) proc;
+ ::java::io::BufferedWriter * out;
+ ::java::io::BufferedReader * in;
+ ::gnu::gcj::runtime::NameFinder * this$0;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_NameFinder$Addr2Line__
diff --git a/libjava/gnu/gcj/runtime/NameFinder.h b/libjava/gnu/gcj/runtime/NameFinder.h
new file mode 100644
index 000000000..38fd98bab
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/NameFinder.h
@@ -0,0 +1,50 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_NameFinder__
+#define __gnu_gcj_runtime_NameFinder__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class NameFinder;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::NameFinder : public ::java::lang::Object
+{
+
+public: // actually package-private
+ static jboolean showRaw();
+ static jboolean removeUnknown();
+public:
+ NameFinder();
+ virtual ::java::lang::String * getSourceFile();
+ virtual jint getLineNum();
+ virtual void lookup(::java::lang::String *, jlong);
+ static ::java::lang::String * demangleInterpreterMethod(::java::lang::String *, ::java::lang::String *);
+ virtual void close();
+private:
+ ::java::lang::String * __attribute__((aligned(__alignof__( ::java::lang::Object)))) binaryFile;
+ ::java::lang::String * sourceFile;
+ jint lineNum;
+ ::java::util::HashMap * procs;
+ static ::java::util::Set * blacklist;
+ static jboolean use_addr2line;
+ static jboolean show_raw;
+ static jboolean remove_unknown;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_NameFinder__
diff --git a/libjava/gnu/gcj/runtime/NameFinder.java b/libjava/gnu/gcj/runtime/NameFinder.java
new file mode 100644
index 000000000..0742af193
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/NameFinder.java
@@ -0,0 +1,341 @@
+/* NameFinder.java -- Translates addresses to StackTraceElements.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.runtime;
+
+import gnu.classpath.Configuration;
+import gnu.gcj.RawData;
+
+import java.lang.StringBuffer;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.IOException;
+import java.io.File;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+
+/**
+ * Lookup addresses (represented as longs) to find source & line number info.
+ *
+ * The following system property is available (defaults to true):
+ * <li>
+ * <ul><code>gnu.gcj.runtime.NameFinder.use_addr2line</code>
+ * Whether an external process, addr2line, should be used to look up
+ * source file and line number info. Throwable.printStackTrace() will
+ * be faster if this property is set to 'false'.
+ * </ul>
+ * <ul><code>gnu.gcj.runtime.NameFinder.remove_unknown</code>
+ * Whether calls to unknown functions (class and method names are unknown)
+ * should be removed from the stack trace. </ul>
+ * </li>
+ *
+ * <code>close()</code> should be called to get rid of all resources.
+ *
+ * This class is used from <code>java.lang.VMThrowable</code>.
+ *
+ * @author Mark Wielaard (mark@klomp.org)
+ */
+public class NameFinder
+{
+ /**
+ * The name of the binary to look up.
+ */
+ private String binaryFile;
+ private String sourceFile;
+ private int lineNum;
+ private HashMap procs = new HashMap();
+ /**
+ * Set of binary files that addr2line should not be called on.
+ */
+ private static Set blacklist = Collections.synchronizedSet(new HashSet());
+
+ private static boolean use_addr2line
+ = Boolean.valueOf(System.getProperty
+ ("gnu.gcj.runtime.NameFinder.use_addr2line", "true")
+ ).booleanValue();
+
+ private static boolean show_raw
+ = Boolean.valueOf(System.getProperty
+ ("gnu.gcj.runtime.NameFinder.show_raw", "false")
+ ).booleanValue();
+
+ /**
+ * Return true if raw addresses should be printed in stacktraces
+ * when no line number information is available.
+ */
+ static final boolean showRaw()
+ {
+ return show_raw;
+ }
+
+ private static final boolean remove_unknown
+ = Boolean.valueOf(System.getProperty
+ ("gnu.gcj.runtime.NameFinder.remove_unknown", "true")
+ ).booleanValue();
+
+ /**
+ * Return true if non-Java frames should be removed from stack
+ * traces.
+ */
+ static final boolean removeUnknown()
+ {
+ return remove_unknown;
+ }
+
+ class Addr2Line
+ {
+ Process proc;
+ BufferedWriter out;
+ BufferedReader in;
+
+ Addr2Line(String binaryFile)
+ {
+ try
+ {
+ String[] exec = new String[] {"addr2line", "-e", binaryFile};
+ Runtime runtime = Runtime.getRuntime();
+ proc = runtime.exec(exec);
+ }
+ catch (IOException ioe)
+ {
+ }
+
+ if (proc != null)
+ {
+ in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+ out = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
+ }
+ }
+
+ void close()
+ {
+ try
+ {
+ if (in != null)
+ in.close();
+ if (out != null)
+ out.close();
+ }
+ catch (IOException x) {}
+ if (proc != null)
+ proc.destroy();
+ }
+ }
+
+ /**
+ * Create a new NameFinder to lookup names in binaryFile. Call close to get rid of any
+ * resources created while using the <code>lookup</code> methods.
+ */
+ public NameFinder()
+ {
+ }
+
+ /**
+ * Returns the source file name if lookup() was successful. If the source file could not be
+ * determined, the binary name will be returned instead.
+ */
+ public String getSourceFile()
+ {
+ String file;
+ if (sourceFile != null)
+ file = sourceFile;
+ else
+ file = binaryFile;
+
+ return file.substring(file.lastIndexOf(File.separator) + 1, file.length());
+ }
+
+ /**
+ * If lookup() was successful, returns the line number of addr. If the line number could not
+ * be determined, -1 is returned.
+ */
+ public int getLineNum()
+ {
+ return lineNum;
+ }
+
+ public void lookup (String file, long addr)
+ {
+ binaryFile = file;
+ sourceFile = null;
+ lineNum = -1;
+
+ if (! use_addr2line || blacklist.contains(file))
+ return;
+ Addr2Line addr2line = (Addr2Line) procs.get(file);
+ if (addr2line == null)
+ {
+ addr2line = new Addr2Line(file);
+ procs.put(file, addr2line);
+ }
+
+ if (addr2line.proc == null)
+ {
+ use_addr2line = false;
+ return;
+ }
+
+ String hexAddr = "0x" + Long.toHexString(addr);
+ String name;
+
+ try
+ {
+ addr2line.out.write(hexAddr);
+ addr2line.out.newLine();
+ addr2line.out.flush();
+ String result = addr2line.in.readLine();
+
+ if (result.indexOf("??") == -1)
+ {
+ int split = result.lastIndexOf(':');
+ sourceFile = result.substring(0, split);
+ String lineNumStr = result.substring(split + 1, result.length());
+ lineNum = Integer.parseInt (lineNumStr);
+ }
+ else
+ {
+ /* This binary has no debug info (assuming addr was valid).
+ Avoid repeat addr2line invocations. */
+ blacklist.add(binaryFile);
+ }
+ }
+ catch (IOException ioe)
+ {
+ addr2line = null;
+ }
+ catch (NumberFormatException x)
+ {
+ }
+ }
+
+ /**
+ * Returns human readable method name and aguments given a method type
+ * signature as known to the interpreter and a classname.
+ */
+ public static String demangleInterpreterMethod(String m, String cn)
+ {
+ int index = 0;
+ int length = m.length();
+ StringBuffer sb = new StringBuffer(length);
+
+ // Figure out the real method name
+ if (m.startsWith("<init>"))
+ {
+ String className;
+ int i = cn.lastIndexOf('.');
+ if (i < 0)
+ className = cn;
+ else
+ className = cn.substring(i + 1);
+ sb.append(className);
+ index += 7;
+ }
+ else
+ {
+ int i = m.indexOf('(');
+ if (i > 0)
+ {
+ sb.append(m.substring(0,i));
+ index += i + 1;
+ }
+ }
+
+ sb.append('(');
+
+ // Demangle the type arguments
+ int arrayDepth = 0;
+ char c = (index < length) ? m.charAt(index) : ')';
+ while (c != ')')
+ {
+ String type;
+ switch(c)
+ {
+ case 'B':
+ type = "byte";
+ break;
+ case 'C':
+ type = "char";
+ break;
+ case 'D':
+ type = "double";
+ break;
+ case 'F':
+ type = "float";
+ break;
+ case 'I':
+ type = "int";
+ break;
+ case 'J':
+ type = "long";
+ break;
+ case 'S':
+ type = "short";
+ break;
+ case 'Z':
+ type = "boolean";
+ break;
+ case 'L':
+ int i = m.indexOf(';', index);
+ if (i > 0)
+ {
+ type = m.substring(index+1, i);
+ index = i;
+ }
+ else
+ type = "<unknown ref>";
+ break;
+ case '[':
+ type = "";
+ arrayDepth++;
+ break;
+ default:
+ type = "<unknown " + c + '>';
+ }
+ sb.append(type);
+
+ // Handle arrays
+ if (c != '[' && arrayDepth > 0)
+ while (arrayDepth > 0)
+ {
+ sb.append("[]");
+ arrayDepth--;
+ }
+
+ index++;
+ char nc = (index < length) ? m.charAt(index) : ')';
+ if (c != '[' && nc != ')')
+ sb.append(", ");
+ c = nc;
+ }
+
+ // Stop. We are not interested in the return type.
+ sb.append(')');
+ return sb.toString();
+ }
+
+ /**
+ * Releases all resources used by this NameFinder.
+ */
+ public void close()
+ {
+ Iterator itr = procs.values().iterator();
+ while (itr.hasNext())
+ {
+ Addr2Line proc = (Addr2Line) itr.next();
+ proc.close();
+ }
+ }
+}
diff --git a/libjava/gnu/gcj/runtime/PersistentByteMap$AccessMode.h b/libjava/gnu/gcj/runtime/PersistentByteMap$AccessMode.h
new file mode 100644
index 000000000..2cd93fad8
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/PersistentByteMap$AccessMode.h
@@ -0,0 +1,49 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_PersistentByteMap$AccessMode__
+#define __gnu_gcj_runtime_PersistentByteMap$AccessMode__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class PersistentByteMap$AccessMode;
+ }
+ }
+ }
+ namespace java
+ {
+ namespace nio
+ {
+ namespace channels
+ {
+ class FileChannel$MapMode;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::PersistentByteMap$AccessMode : public ::java::lang::Object
+{
+
+ PersistentByteMap$AccessMode(::java::nio::channels::FileChannel$MapMode *);
+public: // actually package-private
+ static ::java::nio::channels::FileChannel$MapMode * access$0(::gnu::gcj::runtime::PersistentByteMap$AccessMode *);
+private:
+ ::java::nio::channels::FileChannel$MapMode * __attribute__((aligned(__alignof__( ::java::lang::Object)))) mapMode;
+public:
+ static ::gnu::gcj::runtime::PersistentByteMap$AccessMode * READ_ONLY;
+ static ::gnu::gcj::runtime::PersistentByteMap$AccessMode * READ_WRITE;
+ static ::gnu::gcj::runtime::PersistentByteMap$AccessMode * PRIVATE;
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_PersistentByteMap$AccessMode__
diff --git a/libjava/gnu/gcj/runtime/PersistentByteMap$ByteWrapper.h b/libjava/gnu/gcj/runtime/PersistentByteMap$ByteWrapper.h
new file mode 100644
index 000000000..39cad37d3
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/PersistentByteMap$ByteWrapper.h
@@ -0,0 +1,42 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_PersistentByteMap$ByteWrapper__
+#define __gnu_gcj_runtime_PersistentByteMap$ByteWrapper__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class PersistentByteMap;
+ class PersistentByteMap$ByteWrapper;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::PersistentByteMap$ByteWrapper : public ::java::lang::Object
+{
+
+public:
+ PersistentByteMap$ByteWrapper(::gnu::gcj::runtime::PersistentByteMap *, JArray< jbyte > *);
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+public: // actually package-private
+ JArray< jbyte > * __attribute__((aligned(__alignof__( ::java::lang::Object)))) bytes;
+ jint hash;
+ ::gnu::gcj::runtime::PersistentByteMap * this$0;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_PersistentByteMap$ByteWrapper__
diff --git a/libjava/gnu/gcj/runtime/PersistentByteMap$HashIterator.h b/libjava/gnu/gcj/runtime/PersistentByteMap$HashIterator.h
new file mode 100644
index 000000000..65df6ceea
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/PersistentByteMap$HashIterator.h
@@ -0,0 +1,44 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_PersistentByteMap$HashIterator__
+#define __gnu_gcj_runtime_PersistentByteMap$HashIterator__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class PersistentByteMap;
+ class PersistentByteMap$HashIterator;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::PersistentByteMap$HashIterator : public ::java::lang::Object
+{
+
+public: // actually package-private
+ PersistentByteMap$HashIterator(::gnu::gcj::runtime::PersistentByteMap *, jint);
+public:
+ jboolean hasNext();
+ ::java::lang::Object * next();
+ void remove();
+private:
+ jint __attribute__((aligned(__alignof__( ::java::lang::Object)))) idx;
+ jint count;
+ jint type;
+public: // actually package-private
+ ::gnu::gcj::runtime::PersistentByteMap * this$0;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_PersistentByteMap$HashIterator__
diff --git a/libjava/gnu/gcj/runtime/PersistentByteMap$MapEntry.h b/libjava/gnu/gcj/runtime/PersistentByteMap$MapEntry.h
new file mode 100644
index 000000000..7cb8b63f0
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/PersistentByteMap$MapEntry.h
@@ -0,0 +1,40 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_PersistentByteMap$MapEntry__
+#define __gnu_gcj_runtime_PersistentByteMap$MapEntry__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class PersistentByteMap$MapEntry;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::PersistentByteMap$MapEntry : public ::java::lang::Object
+{
+
+public:
+ PersistentByteMap$MapEntry(jint, ::java::lang::Object *, ::java::lang::Object *);
+ ::java::lang::Object * getKey();
+ ::java::lang::Object * getValue();
+ jint getBucket();
+private:
+ ::java::lang::Object * __attribute__((aligned(__alignof__( ::java::lang::Object)))) key;
+ ::java::lang::Object * value;
+ jint bucket;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_PersistentByteMap$MapEntry__
diff --git a/libjava/gnu/gcj/runtime/PersistentByteMap.h b/libjava/gnu/gcj/runtime/PersistentByteMap.h
new file mode 100644
index 000000000..1bac1d2c0
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/PersistentByteMap.h
@@ -0,0 +1,115 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_PersistentByteMap__
+#define __gnu_gcj_runtime_PersistentByteMap__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class PersistentByteMap;
+ class PersistentByteMap$AccessMode;
+ }
+ }
+ }
+ namespace java
+ {
+ namespace nio
+ {
+ class MappedByteBuffer;
+ namespace channels
+ {
+ class FileChannel;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::PersistentByteMap : public ::java::lang::Object
+{
+
+ PersistentByteMap(::java::io::File *);
+public:
+ PersistentByteMap(::java::lang::String *, ::gnu::gcj::runtime::PersistentByteMap$AccessMode *);
+ PersistentByteMap(::java::io::File *, ::gnu::gcj::runtime::PersistentByteMap$AccessMode *);
+private:
+ void init(::gnu::gcj::runtime::PersistentByteMap *, ::java::io::File *, jint, jint);
+public:
+ static ::gnu::gcj::runtime::PersistentByteMap * emptyPersistentByteMap(::java::io::File *, jint, jint);
+private:
+ jint getWord(jint);
+ void putWord(jint, jint);
+public:
+ virtual ::java::util::Set * entrySet();
+private:
+ jint getBucket(jint);
+ jint getKeyPos(jint);
+ jint getValuePos(jint);
+ void putKeyPos(jint, jint);
+ void putValuePos(jint, jint);
+ JArray< jbyte > * getBytes(jint);
+ jint hash(JArray< jbyte > *);
+public:
+ virtual JArray< jbyte > * get(JArray< jbyte > *);
+ virtual void put(JArray< jbyte > *, JArray< jbyte > *);
+private:
+ jint addBytes(JArray< jbyte > *);
+public:
+ virtual ::java::util::Iterator * iterator(jint);
+ virtual jint size();
+ virtual jint stringTableSize();
+ virtual jint capacity();
+ virtual void force();
+ virtual ::java::io::File * getFile();
+ virtual void close();
+ virtual void putAll(::gnu::gcj::runtime::PersistentByteMap *);
+public: // actually package-private
+ static jint access$0(::gnu::gcj::runtime::PersistentByteMap *);
+ static jint access$1(::gnu::gcj::runtime::PersistentByteMap *);
+ static jint access$2(::gnu::gcj::runtime::PersistentByteMap *, jint);
+ static jint access$3(::gnu::gcj::runtime::PersistentByteMap *, jint);
+ static JArray< jbyte > * access$4(::gnu::gcj::runtime::PersistentByteMap *, jint);
+private:
+ ::java::nio::MappedByteBuffer * __attribute__((aligned(__alignof__( ::java::lang::Object)))) buf;
+ static const jint MAGIC = 0;
+ static const jint VERSION = 4;
+ static const jint CAPACITY = 8;
+ static const jint TABLE_BASE = 12;
+ static const jint STRING_BASE = 16;
+ static const jint STRING_SIZE = 20;
+ static const jint FILE_SIZE = 24;
+ static const jint ELEMENTS = 28;
+ static const jint INT_SIZE = 4;
+ static const jint TABLE_ENTRY_SIZE = 8;
+ jint capacity__;
+ jint table_base;
+ jint string_base;
+ jint string_size;
+ jint file_size;
+ jint elements;
+ jlong length;
+ ::java::io::File * name;
+ static const jint UNUSED_ENTRY = -1;
+public:
+ static const jint KEYS = 0;
+ static const jint VALUES = 1;
+ static const jint ENTRIES = 2;
+private:
+ ::java::util::HashMap * values;
+public: // actually package-private
+ ::java::nio::channels::FileChannel * fc;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_PersistentByteMap__
diff --git a/libjava/gnu/gcj/runtime/PersistentByteMap.java b/libjava/gnu/gcj/runtime/PersistentByteMap.java
new file mode 100644
index 000000000..fec30806f
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/PersistentByteMap.java
@@ -0,0 +1,619 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+
+
+/* A PersistentByteMap maps a byte array to another byte array. It
+uses a file that does not need to be serialized but may be
+memory-mapped and read in-place. So, even if there are many instances
+of gcj applications running, they can share PersistentByteMaps.
+
+The idea is to make searches as fast as possible: opening a
+PersistentByteMap is cheap and search time doesn't grow with the
+number of entries in the table. On the other hand, enumerating the
+map is slow, but that is a relatively uncommon operation.
+
+The main use of this class is to provide a way to map the
+MessageDigest of a class file to the location of a DSO that contains
+the compiled version of that class. It is up the the installer of an
+application to keep the DSO up to date with the jar.
+
+USAGE:
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ digest = md.digest(bytes);
+
+ PersistentByteMap map
+ = new PersistentByteMap
+ (fileName, PersistentByteMap.AccessMode.READ_ONLY);
+
+ byte[] soName = map.get(digest);
+ if (soName)
+ {
+ String SharedLibraryName = new String(soName);
+
+BUGS/FEATURES:
+ remove() isn't written yet.
+
+ capacity is fixed once the map has been created.
+
+ We use linear probing to resolve collisions. It might be
+ better to use a scheme that results in fewer probes to
+ determine that an item isn't found. However, even when the
+ table is half full there are only on average 1.5 probes for a
+ successful search and 2.5 probes for an unsuccessful one.
+
+ We don't do any locking at all: adding to a PersistentByteMap
+ at runtime is possible, but it requires filesystem locks
+ around get(), put(), and remove().
+*/
+
+package gnu.gcj.runtime;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.util.*;
+import java.security.MessageDigest;
+import java.math.BigInteger;
+
+public class PersistentByteMap
+{
+ private MappedByteBuffer buf;
+
+ static private final int MAGIC = 0;
+ static private final int VERSION = 4;
+ static private final int CAPACITY = 8;
+ static private final int TABLE_BASE = 12;
+ static private final int STRING_BASE = 16;
+ static private final int STRING_SIZE = 20;
+ static private final int FILE_SIZE = 24;
+ static private final int ELEMENTS = 28;
+
+ static private final int INT_SIZE = 4;
+
+ static private final int TABLE_ENTRY_SIZE = 2 * INT_SIZE;
+
+ private int capacity; // number of entries
+ private int table_base; // offset from start of file, in bytes
+ private int string_base; // offset from start of file, in bytes
+ private int string_size; // size of string table, in bytes
+ private int file_size; // size of file, in bytes;
+ private int elements; // number of elements in table
+
+ private long length; // the length of the underlying file
+
+ private final File name; // The name of the underlying file
+
+ static private final int UNUSED_ENTRY = -1;
+
+ static public final int KEYS = 0;
+ static public final int VALUES = 1;
+ static public final int ENTRIES = 2;
+
+ private HashMap values; // A map of strings in the string table.
+
+ FileChannel fc; // The underlying file channel.
+
+ static final public class AccessMode
+ {
+ private final FileChannel.MapMode mapMode;
+
+ static
+ {
+ READ_ONLY = new AccessMode(FileChannel.MapMode.READ_ONLY);
+ READ_WRITE = new AccessMode(FileChannel.MapMode.READ_WRITE);
+ PRIVATE = new AccessMode(FileChannel.MapMode.PRIVATE);
+ }
+
+ public static final AccessMode READ_ONLY;
+ public static final AccessMode READ_WRITE;
+ public static final AccessMode PRIVATE;
+
+ private AccessMode(FileChannel.MapMode mode)
+ {
+ this.mapMode = mode;
+ }
+ }
+
+ private PersistentByteMap(File name)
+ {
+ this.name = name;
+ }
+
+ public PersistentByteMap(String filename, AccessMode mode)
+ throws IOException
+ {
+ this(new File(filename), mode);
+ }
+
+ public PersistentByteMap(File f, AccessMode mode)
+ throws IOException
+ {
+ name = f;
+
+ if (mode == AccessMode.READ_ONLY)
+ {
+ FileInputStream fis = new FileInputStream(f);
+ fc = fis.getChannel();
+ }
+ else
+ {
+ RandomAccessFile fos = new RandomAccessFile(f, "rw");
+ fc = fos.getChannel();
+ }
+
+ length = fc.size();
+ buf = fc.map(mode.mapMode, 0, length);
+
+ int magic = getWord (MAGIC);
+ if (magic != 0x67636a64) /* "gcjd" */
+ throw new IllegalArgumentException(f.getName());
+
+ table_base = getWord (TABLE_BASE);
+ capacity = getWord (CAPACITY);
+ string_base = getWord (STRING_BASE);
+ string_size = getWord (STRING_SIZE);
+ file_size = getWord (FILE_SIZE);
+ elements = getWord (ELEMENTS);
+
+ // FIXME: Insert a bunch of sanity checks here
+ }
+
+ private void init (PersistentByteMap m, File f, int capacity, int strtabSize)
+ throws IOException
+ {
+ f.createNewFile();
+ RandomAccessFile raf = new RandomAccessFile(f, "rw");
+
+ {
+ // The user has explicitly provided a size for the table.
+ // We're going to make that size prime. This isn't
+ // strictly necessary but it can't hurt.
+ //
+ // We expand the size by 3/2 and round the result because the
+ // hash table is intolerably slow when more than 2/3 full.
+
+ BigInteger size = new BigInteger(Integer.toString(((capacity*3)+1)/2));
+ BigInteger two = BigInteger.ONE.add(BigInteger.ONE);
+
+ if (size.getLowestSetBit() != 0) // A hard way to say isEven()
+ size = size.add(BigInteger.ONE);
+
+ while (! size.isProbablePrime(10))
+ size = size.add(two);
+
+ this.capacity = capacity = size.intValue();
+ }
+
+ table_base = 64;
+ string_base = table_base + capacity * TABLE_ENTRY_SIZE;
+ string_size = 0;
+ file_size = string_base;
+ elements = 0;
+
+ int totalFileSize = string_base + strtabSize;
+
+ // Create the file; this rounds up the size of the file to a fixed
+ // number of 4k pages.
+ byte[] _4k = new byte[4096];
+ for (long i = 0; i < totalFileSize; i+= 4096)
+ raf.write(_4k);
+
+ fc = raf.getChannel();
+ buf = fc.map(FileChannel.MapMode.READ_WRITE, 0, raf.length());
+
+ for (int i = 0; i < capacity; i++)
+ putKeyPos(UNUSED_ENTRY, i);
+
+ putWord(0x67636a64, MAGIC);
+ putWord(0x01, VERSION);
+ putWord(capacity, CAPACITY);
+ putWord(table_base, TABLE_BASE);
+ putWord(string_base, STRING_BASE);
+ putWord(file_size, FILE_SIZE);
+ putWord(elements, ELEMENTS);
+ buf.force();
+
+ length = fc.size();
+ string_size = 0;
+ }
+
+ static public PersistentByteMap
+ emptyPersistentByteMap(File name, int capacity, int strtabSize)
+ throws IOException
+ {
+ PersistentByteMap m = new PersistentByteMap(name);
+ m.init(m, name, capacity, strtabSize);
+ return m;
+ }
+
+ private int getWord (int index)
+ {
+ buf.position(index);
+ byte[] wordBuf = new byte[4];
+ buf.get(wordBuf);
+
+ int result = (int)wordBuf[0]&0xff;
+ result += ((int)wordBuf[1]&0xff) << 8;
+ result += ((int)wordBuf[2]&0xff) << 16;
+ result += ((int)wordBuf[3]&0xff) << 24;
+ return result;
+ }
+
+ private void putWord (int word, int index)
+ {
+ buf.position(index);
+ byte[] wordBuf = new byte[4];
+ wordBuf[0] = (byte)(word);
+ wordBuf[1] = (byte)(word >>> 8);
+ wordBuf[2] = (byte)(word >>> 16);
+ wordBuf[3] = (byte)(word >>> 24);
+ buf.put(wordBuf);
+ }
+
+ public Set entrySet()
+ {
+ return null;
+ }
+
+ private int getBucket(int n)
+ {
+ return table_base + (2*n * INT_SIZE);
+ }
+
+ private int getKeyPos(int n)
+ {
+ return getWord(getBucket(n));
+ }
+
+ private int getValuePos(int n)
+ {
+ return getWord(getBucket(n) + INT_SIZE);
+ }
+
+ private void putKeyPos(int index, int n)
+ {
+ putWord(index, getBucket(n));
+ }
+
+ private void putValuePos(int index, int n)
+ {
+ putWord(index, getBucket(n) + INT_SIZE);
+ }
+
+ private byte[] getBytes(int n)
+ {
+ int len = getWord (string_base + n);
+ int base = string_base + n + INT_SIZE;
+ byte[] key = new byte[len];
+ buf.position(base);
+ buf.get(key, 0, len);
+ return key;
+ }
+
+ private int hash (byte[] b)
+ {
+ // We assume that the message digest is evenly distributed, so we
+ // only need to use a few bytes of it as the hash function.
+ long hashIndex
+ = ((b[0]&0xffL)
+ + ((b[1]&0xffL)<<8)
+ + ((b[2]&0xffL)<<16)
+ + ((b[3]&0xffL)<<24));
+ long result = hashIndex % (long)capacity;
+ return (int)result;
+ }
+
+ public byte[] get(byte[] digest)
+ {
+ int hashIndex = hash(digest);
+
+ do
+ {
+ int k = getKeyPos(hashIndex);
+ if (k == UNUSED_ENTRY)
+ return null;
+
+ if (Arrays.equals ((byte[])digest, getBytes(k)))
+ return getBytes(getValuePos(hashIndex));
+
+ // Use linear probing to resolve hash collisions. This may
+ // not be theoretically as good as open addressing, but it has
+ // good cache behviour.
+ hashIndex++;
+ hashIndex %= capacity;
+ }
+ while (true);
+ }
+
+ public void put(byte[] digest, byte[] value)
+ throws IllegalAccessException
+ {
+ int hashIndex = hash(digest);
+
+ if (elements >= capacity())
+ throw new IllegalAccessException("Table Full: " + elements);
+
+ do
+ {
+ int k = getKeyPos(hashIndex);
+ if (k == UNUSED_ENTRY)
+ {
+ int newKey = addBytes(digest);
+ putKeyPos(newKey, hashIndex);
+ int newValue = addBytes(value);
+ putValuePos(newValue, hashIndex);
+ elements++;
+ putWord(elements, ELEMENTS);
+ return;
+ }
+ else if (Arrays.equals (digest, getBytes(k)))
+ {
+ int newValue = addBytes((byte[])value);
+ putValuePos(newValue, hashIndex);
+ return;
+ }
+
+ hashIndex++;
+ hashIndex %= capacity;
+ }
+ while (true);
+ }
+
+ private int addBytes (byte[] data)
+ throws IllegalAccessException
+ {
+ if (data.length > 16)
+ {
+ // Keep track of long strings in the hope that we will be able
+ // to re-use them.
+ if (values == null)
+ {
+ values = new HashMap();
+
+ for (int i = 0; i < capacity; i++)
+ if (getKeyPos(i) != UNUSED_ENTRY)
+ {
+ int pos = getValuePos(i);
+ ByteWrapper bytes = new ByteWrapper(getBytes(pos));
+ values.put(bytes, new Integer(pos));
+ }
+ }
+
+ {
+ Object result = values.get(new ByteWrapper(data));
+ if (result != null)
+ {
+ // We already have this value in the string table
+ return ((Integer)result).intValue();
+ }
+ }
+ }
+
+ if (data.length + INT_SIZE >= this.length)
+ throw new IllegalAccessException("String table Full");
+
+ int extent = string_base+string_size;
+ int top = extent;
+ putWord(data.length, extent);
+ extent += INT_SIZE;
+ buf.position(extent);
+ buf.put(data, 0, data.length);
+ extent += data.length;
+ extent += INT_SIZE-1;
+ extent &= ~(INT_SIZE-1); // align
+ string_size = extent - string_base;
+ file_size = extent;
+ putWord (string_size, STRING_SIZE);
+ putWord (file_size, FILE_SIZE);
+
+ if (data.length > 16)
+ values.put(new ByteWrapper(data), new Integer(top - string_base));
+
+ return top - string_base;
+ }
+
+ public Iterator iterator(int type)
+ {
+ return new HashIterator(type);
+ }
+
+ public int size()
+ {
+ return elements;
+ }
+
+ public int stringTableSize()
+ {
+ return string_size;
+ }
+
+ public int capacity()
+ {
+ // With the the table 2/3 full there will be on average 2 probes
+ // for a successful search and 5 probes for an unsuccessful one.
+ return capacity * 2/3;
+ }
+
+ public void force()
+ {
+ buf.force();
+ }
+
+ public File getFile()
+ {
+ return name;
+ }
+
+ // Close the map. Once this has been done, the map can no longer be
+ // used.
+ public void close() throws IOException
+ {
+ force();
+ fc.close();
+ }
+
+ public void
+ putAll(PersistentByteMap t)
+ throws IllegalAccessException
+ {
+ // We can use a fast copy if the size of a map has not changed.
+ if (this.elements == 0 && t.capacity == this.capacity
+ && t.length == this.length)
+ {
+ this.buf.position(0);
+ t.buf.position(0);
+ this.buf.put(t.buf);
+ this.table_base = t.table_base;
+ this.string_base = t.string_base;
+ this.string_size = t.string_size;
+ this.file_size = t.file_size;
+ this.elements = t.elements;
+ if (t.values != null)
+ this.values = (HashMap)t.values.clone();
+ return;
+ }
+
+ // Otherwise do it the hard way.
+ Iterator iterator = t.iterator(PersistentByteMap.ENTRIES);
+ while (iterator.hasNext())
+ {
+ PersistentByteMap.MapEntry entry
+ = (PersistentByteMap.MapEntry)iterator.next();
+ this.put((byte[])entry.getKey(), (byte[])entry.getValue());
+ }
+ }
+
+
+ private final class HashIterator implements Iterator
+ {
+ /** Current index in the physical hash table. */
+
+ private int idx;
+ private int count;
+ private final int type;
+
+ /**
+ * Construct a new HashIterator with the supplied type.
+ * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES}
+ */
+ HashIterator(int type)
+ {
+ this.type = type;
+ count = elements;
+ idx = 0;
+ }
+
+ /**
+ * Returns true if the Iterator has more elements.
+ * @return true if there are more elements
+ * @throws ConcurrentModificationException if the HashMap was modified
+ */
+ public boolean hasNext()
+ {
+ return count > 0;
+ }
+
+ /**
+ * Returns the next element in the Iterator's sequential view.
+ * @return the next element
+ * @throws ConcurrentModificationException if the HashMap was modified
+ * @throws NoSuchElementException if there is none
+ */
+ public Object next()
+ {
+ count--;
+ for (int i = idx; i < capacity; i++)
+ if (getKeyPos(i) != UNUSED_ENTRY)
+ {
+ idx = i+1;
+ if (type == VALUES)
+ return getBytes(getValuePos(i));
+ if (type == KEYS)
+ return getBytes(getKeyPos(i));
+ return new MapEntry(i,
+ getBytes(getKeyPos(i)),
+ getBytes(getValuePos(i)));
+ }
+ return null;
+ }
+
+ /**
+ * Remove from the underlying collection the last element returned
+ * by next (optional operation). This method can be called only
+ * once after each call to <code>next()</code>. It does not affect
+ * what will be returned by subsequent calls to next.
+ *
+ * @throws IllegalStateException if next has not yet been called
+ * or remove has already been called since the last call
+ * to next.
+ * @throws UnsupportedOperationException if this Iterator does not
+ * support the remove operation.
+ */
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ static public final class MapEntry
+ {
+ private final Object key;
+ private final Object value;
+ private final int bucket;
+
+ public MapEntry(int bucket, Object newKey, Object newValue)
+ {
+ this.key = newKey;
+ this.value = newValue;
+ this.bucket = bucket;
+ }
+
+ public final Object getKey()
+ {
+ return key;
+ }
+
+ public final Object getValue()
+ {
+ return value;
+ }
+
+ public final int getBucket()
+ {
+ return bucket;
+ }
+ }
+
+ // A wrapper class for a byte array that allows collections to be
+ // made.
+ private final class ByteWrapper
+ {
+ final byte[] bytes;
+ final int hash;
+
+ public ByteWrapper (byte[] bytes)
+ {
+ int sum = 0;
+ this.bytes = bytes;
+ for (int i = 0; i < bytes.length; i++)
+ sum += bytes[i];
+ hash = sum;
+ }
+
+ public int hashCode()
+ {
+ return hash;
+ }
+
+ public boolean equals(Object obj)
+ {
+ return Arrays.equals(bytes, ((ByteWrapper)obj).bytes);
+ }
+ }
+}
diff --git a/libjava/gnu/gcj/runtime/SharedLibHelper.h b/libjava/gnu/gcj/runtime/SharedLibHelper.h
new file mode 100644
index 000000000..b2900b7e0
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/SharedLibHelper.h
@@ -0,0 +1,76 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_SharedLibHelper__
+#define __gnu_gcj_runtime_SharedLibHelper__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ class Core;
+ class RawData;
+ namespace runtime
+ {
+ class SharedLibHelper;
+ }
+ }
+ }
+ namespace java
+ {
+ namespace net
+ {
+ class URL;
+ }
+ namespace security
+ {
+ class CodeSource;
+ class ProtectionDomain;
+ }
+ }
+}
+
+class gnu::gcj::runtime::SharedLibHelper : public ::java::lang::Object
+{
+
+public: // actually package-private
+ SharedLibHelper(::java::lang::String *, ::java::lang::ClassLoader *, ::java::security::CodeSource *, ::java::security::ProtectionDomain *, jint);
+public:
+ static ::gnu::gcj::runtime::SharedLibHelper * findHelper(::java::lang::String *);
+public: // actually package-private
+ static void copyFile(::java::io::File *, ::java::io::File *);
+public:
+ static ::gnu::gcj::runtime::SharedLibHelper * findHelper(::java::lang::ClassLoader *, ::java::lang::String *, ::java::security::CodeSource *, jboolean);
+ static ::gnu::gcj::runtime::SharedLibHelper * findHelper(::java::lang::ClassLoader *, ::java::lang::String *, ::java::security::CodeSource *, ::java::security::ProtectionDomain *, jboolean);
+ virtual void finalize();
+ virtual ::java::lang::Class * findClass(::java::lang::String *);
+ virtual ::java::net::URL * findResource(::java::lang::String *);
+ virtual ::gnu::gcj::Core * findCore(::java::lang::String *);
+public: // actually package-private
+ virtual void ensureInit();
+ virtual jboolean hasResource(::java::lang::String *);
+ virtual void init();
+ virtual void ensureSupersLinked(::java::lang::Class *);
+public:
+ virtual ::java::lang::String * toString();
+public: // actually package-private
+ virtual void registerClass(::java::lang::String *, ::java::lang::Class *);
+ ::gnu::gcj::RawData * __attribute__((aligned(__alignof__( ::java::lang::Object)))) handler;
+ ::gnu::gcj::RawData * core_chain;
+ ::java::util::HashMap * classMap;
+ ::java::lang::ClassLoader * loader;
+ ::java::lang::String * baseName;
+ ::java::security::ProtectionDomain * domain;
+ jint flags;
+ jboolean initialized;
+ static ::java::util::HashMap * map;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_SharedLibHelper__
diff --git a/libjava/gnu/gcj/runtime/SharedLibHelper.java b/libjava/gnu/gcj/runtime/SharedLibHelper.java
new file mode 100644
index 000000000..bdf7c0453
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/SharedLibHelper.java
@@ -0,0 +1,224 @@
+/* Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.runtime;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.security.*;
+import gnu.gcj.Core;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.nio.channels.FileChannel;
+import java.io.*;
+
+public class SharedLibHelper
+{
+ /** Load a shared library, and associate a ClassLoader with it.
+ * @param libname named of shared library (passed to dlopen)
+ * @param parent the parent ClassLoader
+ * @parem flags passed to dlopen
+ */
+ SharedLibHelper(String libname, ClassLoader parent, CodeSource source,
+ ProtectionDomain domain, int flags)
+ {
+ // FIXME: ask security manager first.
+ loader = parent;
+ baseName = libname;
+ if (domain == null)
+ domain = new ProtectionDomain(source,
+ Policy.getPolicy().getPermissions(source));
+ this.domain = domain;
+ this.flags = flags;
+ }
+
+ public static SharedLibHelper findHelper (String libname)
+ {
+ synchronized (map)
+ {
+ Set s = (Set)map.get(libname);
+ if (s == null)
+ return null;
+ for (Iterator i=s.iterator(); i.hasNext();)
+ {
+ WeakReference ref = (WeakReference)i.next();
+ if (ref != null)
+ return (SharedLibHelper) ref.get();
+ }
+ return null;
+ }
+ }
+
+ static void copyFile (File in, File out) throws IOException
+ {
+ FileChannel source = new FileInputStream(in).getChannel();
+ FileChannel destination = new FileOutputStream(out).getChannel();
+ source.transferTo(0, source.size(), destination);
+ source.close();
+ destination.close();
+ }
+
+ public static SharedLibHelper findHelper (ClassLoader loader, String libname,
+ CodeSource source,
+ boolean tryParents)
+ {
+ return findHelper (loader, libname, source, null, tryParents);
+ }
+
+ public static SharedLibHelper findHelper (ClassLoader loader, String libname,
+ CodeSource source,
+ ProtectionDomain domain,
+ boolean tryParents)
+ {
+ synchronized (map)
+ {
+ SharedLibHelper result;
+ Set s = (Set)map.get(libname);
+ if (s == null)
+ {
+ s = new HashSet();
+ map.put(libname, s);
+ }
+ else
+ {
+ for (Iterator i=s.iterator(); i.hasNext();)
+ {
+ WeakReference ref = (WeakReference)i.next();
+ if (ref != null)
+ {
+ result = (SharedLibHelper) ref.get();
+ if (result != null)
+ {
+ // A match succeeds if the library is already
+ // loaded by LOADER or any of its ancestors.
+ ClassLoader l = loader;
+ do
+ {
+ if (result.loader == l)
+ return result;
+ l = l.getParent();
+ }
+ while (tryParents && l != null);
+ }
+ }
+ }
+
+ // Oh dear. We've already mapped this shared library, but
+ // with a different class loader. We need to copy it.
+ try
+ {
+ File copy
+ = File.createTempFile(new File(libname).getName(),
+ ".so", new File ("/tmp"));
+ File src = new File(libname);
+ copyFile (src, copy);
+ copy.deleteOnExit();
+ libname = copy.getPath();
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+ result = new SharedLibHelper(libname, loader, source, domain, 0);
+ s.add(new WeakReference(result));
+ return result;
+ }
+ }
+
+ public native void finalize ();
+
+ public Class findClass(String name)
+ {
+ ensureInit();
+ Class result = (Class) classMap.get(name);
+ if (result != null)
+ {
+ // We never want to return a class without its supers linked.
+ // It isn't clear from the spec, but this is what other
+ // implementations do in practice.
+ ensureSupersLinked(result);
+ }
+ return result;
+ }
+
+ public URL findResource (String name)
+ {
+ ensureInit();
+ if (! hasResource(name))
+ return null;
+ try
+ {
+ return new URL("gcjlib", "", -1, baseName + "!/" + name);
+ }
+ catch (MalformedURLException _)
+ {
+ }
+ return null;
+ }
+
+ public native Core findCore (String name);
+
+ void ensureInit()
+ {
+ synchronized (classMap)
+ {
+ if (initialized)
+ return;
+ init();
+ initialized = true;
+ }
+ }
+
+ native boolean hasResource(String name);
+ native void init();
+ native void ensureSupersLinked(Class k);
+
+ public String toString ()
+ {
+ return "shared object " + baseName;
+ }
+
+ /** Called during dlopen's processing of the init section. */
+ void registerClass(String name, Class cls)
+ {
+ classMap.put(name, cls);
+ }
+
+ /** The handle returned by dlopen. */
+ gnu.gcj.RawData handler;
+
+ /** Holds a _Jv_core_chain for the loader. */
+ gnu.gcj.RawData core_chain;
+
+ /** Map classnames to Classes. */
+ HashMap classMap = new HashMap(20);
+
+ /** Class loader we're helping. */
+ ClassLoader loader;
+
+ /** Name of base file. */
+ String baseName;
+
+ /** Protection domain for loaded classes. */
+ ProtectionDomain domain;
+
+ /** Flags to pass to dlopen. FIXME: platform dependent.
+ 0 is always "sensible" (defined by us). */
+ int flags;
+
+ /** True if we've been initialized. */
+ boolean initialized = false;
+
+ /** Map shared library names to a helper object. This uses weak
+ references in the values so we don't prevent collection. */
+ static HashMap map = new HashMap ();
+}
diff --git a/libjava/gnu/gcj/runtime/SharedLibLoader.h b/libjava/gnu/gcj/runtime/SharedLibLoader.h
new file mode 100644
index 000000000..8a439d3d3
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/SharedLibLoader.h
@@ -0,0 +1,47 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_SharedLibLoader__
+#define __gnu_gcj_runtime_SharedLibLoader__
+
+#pragma interface
+
+#include <java/lang/ClassLoader.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class SharedLibHelper;
+ class SharedLibLoader;
+ }
+ }
+ }
+ namespace java
+ {
+ namespace net
+ {
+ class URL;
+ }
+ }
+}
+
+class gnu::gcj::runtime::SharedLibLoader : public ::java::lang::ClassLoader
+{
+
+public:
+ SharedLibLoader(::java::lang::String *, ::java::lang::ClassLoader *, jint);
+ SharedLibLoader(::java::lang::String *);
+ virtual ::java::lang::Class * findClass(::java::lang::String *);
+ virtual ::java::net::URL * findResource(::java::lang::String *);
+ virtual ::java::util::Enumeration * findResources(::java::lang::String *);
+public: // actually package-private
+ ::gnu::gcj::runtime::SharedLibHelper * __attribute__((aligned(__alignof__( ::java::lang::ClassLoader)))) helper;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_SharedLibLoader__
diff --git a/libjava/gnu/gcj/runtime/SharedLibLoader.java b/libjava/gnu/gcj/runtime/SharedLibLoader.java
new file mode 100644
index 000000000..b8e6a57de
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/SharedLibLoader.java
@@ -0,0 +1,79 @@
+/* Copyright (C) 2001, 2003 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.runtime;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.CodeSource;
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * A ClassLoader backed by a gcj-compiled shared library.
+ * @author Per Bothner <per@bothner.com>, Brainfood Inc.
+ */
+
+public class SharedLibLoader extends ClassLoader
+{
+ /** Load a shared library, and associate a ClassLoader with it.
+ * @param libname named of shared library (passed to dlopen)
+ * @param parent the parent ClassLoader
+ * @parem flags passed to dlopen
+ */
+ public SharedLibLoader(String libname, ClassLoader parent, int flags)
+ {
+ super(parent);
+ URL url;
+ try
+ {
+ url = new URL("file", "", libname);
+ }
+ catch (MalformedURLException _)
+ {
+ url = null;
+ }
+ helper = SharedLibHelper.findHelper(this, libname,
+ new CodeSource(url, null), true);
+ }
+
+ /** Load a shared library, and asociate a ClassLoader with it.
+ * @param libname named of shared library (passed to dlopen)
+ */
+ public SharedLibLoader(String libname)
+ {
+ this(libname, getSystemClassLoader(), 0);
+ }
+
+ public Class findClass(String name)
+ throws ClassNotFoundException
+ {
+ Class cls = helper.findClass(name);
+ if (cls == null)
+ throw new ClassNotFoundException(name);
+ return cls;
+ }
+
+ public URL findResource (String name)
+ {
+ return helper.findResource(name);
+ }
+
+ public Enumeration findResources (String name) throws IOException
+ {
+ URL url = findResource(name);
+ if (url == null)
+ return null;
+ Vector v = new Vector(1);
+ v.add(url);
+ return v.elements();
+ }
+
+ /** The helper that does the work for us. */
+ SharedLibHelper helper;
+}
diff --git a/libjava/gnu/gcj/runtime/StringBuffer.h b/libjava/gnu/gcj/runtime/StringBuffer.h
new file mode 100644
index 000000000..27a3a7e30
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/StringBuffer.h
@@ -0,0 +1,54 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_StringBuffer__
+#define __gnu_gcj_runtime_StringBuffer__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class StringBuffer;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::StringBuffer : public ::java::lang::Object
+{
+
+public:
+ ::gnu::gcj::runtime::StringBuffer * append(jboolean);
+ ::gnu::gcj::runtime::StringBuffer * append(jchar);
+ ::gnu::gcj::runtime::StringBuffer * append(jint);
+ ::gnu::gcj::runtime::StringBuffer * append(jlong);
+ ::gnu::gcj::runtime::StringBuffer * append(jfloat);
+ ::gnu::gcj::runtime::StringBuffer * append(jdouble);
+ ::gnu::gcj::runtime::StringBuffer * append(::java::lang::Object *);
+ ::gnu::gcj::runtime::StringBuffer * append(::java::lang::String *);
+private:
+ void ensureCapacity_unsynchronized(jint);
+public:
+ StringBuffer();
+ StringBuffer(jint);
+ StringBuffer(::java::lang::String *);
+ ::java::lang::String * toString();
+public: // actually package-private
+ jint __attribute__((aligned(__alignof__( ::java::lang::Object)))) count;
+ JArray< jchar > * value;
+private:
+ static const jint DEFAULT_CAPACITY = 16;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_StringBuffer__
diff --git a/libjava/gnu/gcj/runtime/StringBuffer.java b/libjava/gnu/gcj/runtime/StringBuffer.java
new file mode 100644
index 000000000..f9a433e5a
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/StringBuffer.java
@@ -0,0 +1,199 @@
+// This is a simplified copy of java.lang.StringBuffer with
+// `synchronized' removed.
+
+/* StringBuffer.java -- Growable strings
+ Copyright (C) 1998, 1999, 2000, 2001 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.gcj.runtime;
+
+public final class StringBuffer
+{
+ /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
+ * Uses <code>String.valueOf()</code> to convert to
+ * <code>String</code>.
+ * @param bool the <code>boolean</code> to convert and append.
+ * @return this <code>StringBuffer</code>.
+ * @see java.lang.String#valueOf(boolean)
+ */
+ public StringBuffer append (boolean bool)
+ {
+ return append (bool ? "true" : "false");
+ }
+
+ /** Append the <code>char</code> to this <code>StringBuffer</code>.
+ * @param c the <code>char</code> to append.
+ * @return this <code>StringBuffer</code>.
+ */
+ public StringBuffer append (char ch)
+ {
+ ensureCapacity_unsynchronized (count + 1);
+ value[count++] = ch;
+ return this;
+ }
+
+ /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
+ * Uses <code>String.valueOf()</code> to convert to
+ * <code>String</code>.
+ * @param inum the <code>int</code> to convert and append.
+ * @return this <code>StringBuffer</code>.
+ * @see java.lang.String#valueOf(int)
+ */
+ public native StringBuffer append (int inum);
+
+ /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
+ * Uses <code>String.valueOf()</code> to convert to
+ * <code>String</code>.
+ * @param lnum the <code>long</code> to convert and append.
+ * @return this <code>StringBuffer</code>.
+ * @see java.lang.String#valueOf(long)
+ */
+ public StringBuffer append (long lnum)
+ {
+ return append (Long.toString (lnum));
+ }
+
+ /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
+ * Uses <code>String.valueOf()</code> to convert to
+ * <code>String</code>.
+ * @param fnum the <code>float</code> to convert and append.
+ * @return this <code>StringBuffer</code>.
+ * @see java.lang.String#valueOf(float)
+ */
+ public StringBuffer append (float fnum)
+ {
+ return append (Float.toString (fnum));
+ }
+
+ /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
+ * Uses <code>String.valueOf()</code> to convert to
+ * <code>String</code>.
+ * @param dnum the <code>double</code> to convert and append.
+ * @return this <code>StringBuffer</code>.
+ * @see java.lang.String#valueOf(double)
+ */
+ public StringBuffer append (double dnum)
+ {
+ return append (Double.toString (dnum));
+ }
+
+ /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>.
+ * Uses <code>String.valueOf()</code> to convert to
+ * <code>String</code>.
+ * @param obj the <code>Object</code> to convert and append.
+ * @return this <code>StringBuffer</code>.
+ * @see java.lang.String#valueOf(java.lang.Object)
+ */
+ public StringBuffer append (Object obj)
+ {
+ return append (String.valueOf(obj));
+ }
+
+ /** Append the <code>String</code> to this <code>StringBuffer</code>.
+ * @param str the <code>String</code> to append.
+ * @return this <code>StringBuffer</code>.
+ */
+ public StringBuffer append (String str)
+ {
+ if (str == null)
+ str = "null";
+ int len = str.length();
+ ensureCapacity_unsynchronized (count + len);
+ str.getChars(0, len, value, count);
+ count += len;
+ return this;
+ }
+
+ private void ensureCapacity_unsynchronized (int minimumCapacity)
+ {
+ if (minimumCapacity > value.length)
+ {
+ minimumCapacity = Math.max (minimumCapacity, value.length * 2 + 2);
+ char[] nb = new char[minimumCapacity];
+ System.arraycopy(value, 0, nb, 0, count);
+ value = nb;
+ }
+ }
+
+ /** Create a new StringBuffer with default capacity 16.
+ * @see JLS 20.13.1
+ */
+ public StringBuffer ()
+ {
+ this (DEFAULT_CAPACITY);
+ }
+
+ /** Create an empty <code>StringBuffer</code> with the specified initial capacity.
+ * @param capacity the initial capacity.
+ */
+ public StringBuffer (int capacity)
+ {
+ count = 0;
+ value = new char[capacity];
+ }
+
+ /** Create a new <code>StringBuffer</code> with the characters in the specified <code>String</code>.
+ * Initial capacity will be the size of the String plus 16.
+ * @param str the <code>String</code> to make a <code>StringBuffer</code> out of.
+ */
+ public StringBuffer (String str)
+ {
+ if (str == null)
+ str = "null";
+ count = str.length();
+ // JLS: The initial capacity of the string buffer is 16 plus the
+ // length of the argument string.
+ value = new char[count + DEFAULT_CAPACITY];
+ str.getChars(0, count, value, 0);
+ }
+
+ /** Convert this <code>StringBuffer</code> to a <code>String</code>.
+ * @return the characters in this StringBuffer
+ */
+ // This is native because efficient implementation requires avoiding
+ // the Java protection mechanism.
+ public native String toString ();
+
+ // Index of next available character. Note that this has
+ // permissions set this way so that String can get the value.
+ int count;
+
+ // The buffer. Note that this has permissions set this way so that
+ // String can get the value.
+ char[] value;
+
+ private final static int DEFAULT_CAPACITY = 16; // JLS 20.13.1
+}
diff --git a/libjava/gnu/gcj/runtime/SystemClassLoader.h b/libjava/gnu/gcj/runtime/SystemClassLoader.h
new file mode 100644
index 000000000..58c709659
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/SystemClassLoader.h
@@ -0,0 +1,40 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_gcj_runtime_SystemClassLoader__
+#define __gnu_gcj_runtime_SystemClassLoader__
+
+#pragma interface
+
+#include <java/net/URLClassLoader.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class SystemClassLoader;
+ }
+ }
+ }
+}
+
+class gnu::gcj::runtime::SystemClassLoader : public ::java::net::URLClassLoader
+{
+
+public: // actually package-private
+ SystemClassLoader(::java::lang::ClassLoader *);
+ void addClass(::java::lang::Class *);
+public: // actually protected
+ ::java::lang::Class * findClass(::java::lang::String *);
+public: // actually package-private
+ void init();
+private:
+ ::java::util::HashMap * __attribute__((aligned(__alignof__( ::java::net::URLClassLoader)))) nativeClasses;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_gcj_runtime_SystemClassLoader__
diff --git a/libjava/gnu/gcj/runtime/SystemClassLoader.java b/libjava/gnu/gcj/runtime/SystemClassLoader.java
new file mode 100644
index 000000000..7470542cb
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/SystemClassLoader.java
@@ -0,0 +1,113 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.runtime;
+
+import java.io.*;
+import java.lang.reflect.Field;
+import java.util.StringTokenizer;
+import java.util.HashMap;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+public final class SystemClassLoader extends URLClassLoader
+{
+ SystemClassLoader(ClassLoader parent)
+ {
+ super(new URL[0], parent);
+ }
+
+ // This holds all the "native" classes linked into the executable
+ // and registered with this loader.
+ private HashMap nativeClasses = new HashMap();
+
+ // This is called to register a native class which was linked into
+ // the application but which is registered with the system class
+ // loader after the VM is initialized.
+ void addClass(Class klass)
+ {
+ String packageName = null;
+ String className = klass.getName();
+ int lastDot = className.lastIndexOf('.');
+ if (lastDot != -1)
+ packageName = className.substring(0, lastDot);
+ if (packageName != null && getPackage(packageName) == null)
+ {
+ // Should have some way to store this information in a
+ // precompiled manifest.
+ definePackage(packageName, null, null, null, null, null, null, null);
+ }
+
+ // Use reflection to access the package-private "loadedClasses" field.
+ nativeClasses.put(className, klass);
+ }
+
+ protected native Class findClass(String name);
+
+ // We add the URLs to the system class loader late. The reason for
+ // this is that during bootstrap we don't want to parse URLs or
+ // create URL connections, since that will result in circularities
+ // causing a crash.
+ void init()
+ {
+ String sep = File.pathSeparator;
+ StringTokenizer st
+ = new StringTokenizer (System.getProperty ("java.class.path", "."),
+ sep, true);
+ // Pretend we start with a ':', so if we see a ':' first we add
+ // '.'.
+ boolean last_was_sep = true;
+ while (st.hasMoreElements ())
+ {
+ String e = st.nextToken ();
+ try
+ {
+ if (sep.equals(e))
+ {
+ if (last_was_sep)
+ {
+ // We saw two separators in a row, so add ".".
+ addURL(new URL("file", "", -1, "./"));
+ last_was_sep = false;
+ }
+ else
+ last_was_sep = true;
+ continue;
+ }
+
+ last_was_sep = false;
+ File path = new File(e);
+ // Ignore invalid paths.
+ if (!path.exists())
+ continue;
+ if (!e.endsWith (File.separator) && path.isDirectory ())
+ addURL(new URL("file", "", -1, e + File.separator));
+ else
+ addURL(new URL("file", "", -1, e));
+ }
+ catch (java.net.MalformedURLException x)
+ {
+ // This should never happen.
+ throw new RuntimeException(x);
+ }
+ }
+ // If we saw a trailing ":", add "." to the path.
+ if (last_was_sep)
+ {
+ try
+ {
+ addURL(new URL("file", "", -1, "./"));
+ }
+ catch (java.net.MalformedURLException x)
+ {
+ // This should never happen.
+ throw new RuntimeException(x);
+ }
+ }
+ }
+}
diff --git a/libjava/gnu/gcj/runtime/natFinalizerThread.cc b/libjava/gnu/gcj/runtime/natFinalizerThread.cc
new file mode 100644
index 000000000..ec1846baf
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/natFinalizerThread.cc
@@ -0,0 +1,62 @@
+// natFinalizerThread.cc - Implementation of FinalizerThread native methods.
+
+/* Copyright (C) 2001, 2004 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <gnu/gcj/runtime/FinalizerThread.h>
+
+#include <java-threads.h>
+
+static _Jv_Mutex_t mutex;
+static _Jv_ConditionVariable_t condition;
+
+// Initialize lock & condition variable.
+void
+gnu::gcj::runtime::FinalizerThread::init ()
+{
+ _Jv_MutexInit (&mutex);
+ _Jv_CondInit (&condition);
+}
+
+// This is called by the GC when a finalizer is ready to be
+// run. It sets a flag and wakes up the finalizer thread. Note
+// that this MUST NOT aquire any Java lock, as this could result in
+// the hash synchronization code being re-entered: the synchronization
+// code itself might need to allocate. See PR 16478.
+void
+gnu::gcj::runtime::FinalizerThread::finalizerReady ()
+{
+#ifdef __JV_NO_THREADS__
+ _Jv_RunFinalizers ();
+#else
+ _Jv_MutexLock (&mutex);
+ finalizer_ready = true;
+ _Jv_CondNotify (&condition, &mutex);
+ _Jv_MutexUnlock (&mutex);
+#endif
+}
+
+// Main loop for the finalizer thread.
+void
+gnu::gcj::runtime::FinalizerThread::run ()
+{
+ while (true)
+ {
+ _Jv_MutexLock (&mutex);
+ if (! finalizer_ready)
+ _Jv_CondWait (&condition, &mutex, 0, 0);
+ finalizer_ready = false;
+ _Jv_MutexUnlock (&mutex);
+ _Jv_RunFinalizers ();
+ }
+}
diff --git a/libjava/gnu/gcj/runtime/natSharedLibLoader.cc b/libjava/gnu/gcj/runtime/natSharedLibLoader.cc
new file mode 100644
index 000000000..5ae6842d6
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/natSharedLibLoader.cc
@@ -0,0 +1,151 @@
+// natSharedLibLoader.cc - Implementation of SharedLibHelper native methods.
+
+/* Copyright (C) 2001, 2003, 2004, 2005, 2006, 2010 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <execution.h>
+
+#include <gnu/gcj/runtime/SharedLibHelper.h>
+#include <java/io/IOException.h>
+#include <java/lang/UnsupportedOperationException.h>
+#include <java/lang/UnknownError.h>
+
+#include <java/lang/VMClassLoader.h>
+
+// If we're using the Boehm GC, then we need this include to override dlopen.
+#ifdef HAVE_BOEHM_GC
+// Set GC_DEBUG before including gc.h!
+#ifdef LIBGCJ_GC_DEBUG
+# define GC_DEBUG
+#endif
+#include <gc.h>
+#endif /* HAVE_BOEHM_GC */
+
+#ifdef HAVE_DLOPEN
+#include <dlfcn.h>
+
+/* Only used during dlopen, while having a lock on Class.class. */
+static java::lang::ClassLoader *curLoader;
+static gnu::gcj::runtime::SharedLibHelper *curHelper;
+
+typedef void (*ClassHookFunc) (jclass);
+typedef void (*CoreHookFunc) (_Jv_core_chain *);
+
+void
+_Jv_sharedlib_register_hook (jclass cls)
+{
+ cls->protectionDomain = curHelper->domain;
+ cls->loader = curLoader;
+ if (! cls->engine)
+ cls->engine = &_Jv_soleCompiledEngine;
+ curHelper->registerClass(cls->getName(), cls);
+}
+
+static void
+core_hook (_Jv_core_chain *chain)
+{
+ chain->next = (_Jv_core_chain *) curHelper->core_chain;
+ curHelper->core_chain = (gnu::gcj::RawData *) chain;
+}
+
+struct SharedLibDummy
+{
+ ClassHookFunc saved;
+ CoreHookFunc saved_core;
+ SharedLibDummy()
+ {
+ saved = _Jv_RegisterClassHook;
+ saved_core = _Jv_RegisterCoreHook;
+ }
+ ~SharedLibDummy()
+ {
+ _Jv_RegisterClassHook = saved;
+ _Jv_RegisterCoreHook = saved_core;
+ curLoader = NULL;
+ }
+};
+#endif
+
+void
+gnu::gcj::runtime::SharedLibHelper::init(void)
+{
+#ifdef HAVE_DLOPEN
+ char *lname = (char *) __builtin_alloca (JvGetStringUTFLength (baseName)
+ + 1);
+ jsize total = JvGetStringUTFRegion (baseName, 0, baseName->length(), lname);
+ lname[total] = '\0';
+
+ if (flags==0)
+ flags = RTLD_GLOBAL | RTLD_LAZY;
+ JvSynchronize dummy1(&::java::lang::Class::class$);
+ SharedLibDummy dummy2;
+ curLoader = ((void*)loader == ::java::lang::VMClassLoader::bootLoader
+ ? NULL : loader);
+ curHelper = this;
+ _Jv_RegisterClassHook = _Jv_sharedlib_register_hook;
+ _Jv_RegisterCoreHook = core_hook;
+ void *h = dlopen(lname, flags);
+ if (h == NULL)
+ {
+ const char *msg = dlerror();
+ throw new ::java::lang::UnknownError(JvNewStringLatin1(msg));
+ }
+ handler = (gnu::gcj::RawData*) h;
+#else
+ const char *msg
+ = "shared library class loading is not supported on this platform";
+ throw new ::java::lang::UnsupportedOperationException(JvNewStringLatin1(msg));
+#endif
+}
+
+jboolean
+gnu::gcj::runtime::SharedLibHelper::hasResource (jstring name)
+{
+#ifdef HAVE_DLOPEN
+ _Jv_core_chain *node = _Jv_FindCore ((_Jv_core_chain *) core_chain, name);
+ return node != NULL;
+#else
+ return false;
+#endif
+}
+
+#ifdef HAVE_DLOPEN
+extern gnu::gcj::Core *_Jv_create_core (_Jv_core_chain *node, jstring name);
+#endif
+
+gnu::gcj::Core *
+gnu::gcj::runtime::SharedLibHelper::findCore (jstring name)
+{
+#ifdef HAVE_DLOPEN
+ ensureInit();
+ return _Jv_create_core ((_Jv_core_chain *) core_chain, name);
+#else
+ return NULL;
+#endif
+}
+
+void
+gnu::gcj::runtime::SharedLibHelper::finalize()
+{
+ _Jv_FreeCoreChain ((_Jv_core_chain *) core_chain);
+#ifdef HAVE_DLOPEN
+ if (handler)
+ dlclose (handler);
+#endif
+}
+
+void
+gnu::gcj::runtime::SharedLibHelper::ensureSupersLinked(jclass k)
+{
+ _Jv_Linker::wait_for_state (k, JV_STATE_LOADING);
+}
diff --git a/libjava/gnu/gcj/runtime/natStringBuffer.cc b/libjava/gnu/gcj/runtime/natStringBuffer.cc
new file mode 100644
index 000000000..2777b9ed8
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/natStringBuffer.cc
@@ -0,0 +1,36 @@
+// natStringBuffer.cc - Implementation of java.lang.StringBuffer native methods.
+
+/* Copyright (C) 2001 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <gcj/cni.h>
+#include <gnu/gcj/runtime/StringBuffer.h>
+#include <java/lang/String.h>
+
+gnu::gcj::runtime::StringBuffer *
+gnu::gcj::runtime::StringBuffer::append (jint num)
+{
+ // Use an array large enough for "-2147483648"; i.e. 11 chars.
+ jchar buffer[11];
+ int i = _Jv_FormatInt (buffer+11, num);
+ jint needed = count + i;
+ ensureCapacity_unsynchronized (needed);
+ jchar* dst = elements (value) + count;
+ jchar* src = buffer+11-i;
+ while (--i >= 0)
+ *dst++ = *src++;
+ count = needed;
+ return this;
+}
+
+java::lang::String *
+gnu::gcj::runtime::StringBuffer::toString ()
+{
+ return new java::lang::String (this);
+}
diff --git a/libjava/gnu/gcj/runtime/natSystemClassLoader.cc b/libjava/gnu/gcj/runtime/natSystemClassLoader.cc
new file mode 100644
index 000000000..7052bc8e8
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/natSystemClassLoader.cc
@@ -0,0 +1,31 @@
+// natSystemClassLoader.cc - native code for system class loader
+
+/* Copyright (C) Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <execution.h>
+
+#include <gnu/gcj/runtime/SystemClassLoader.h>
+#include <java/lang/ClassNotFoundException.h>
+#include <java/util/HashMap.h>
+
+jclass
+gnu::gcj::runtime::SystemClassLoader::findClass (jstring name)
+{
+ jclass result = (jclass) nativeClasses->get(name);
+ if (! result)
+ return URLClassLoader::findClass(name);
+ // Never return a class whose supers are not installed.
+ _Jv_Linker::wait_for_state (result, JV_STATE_LOADING);
+ return result;
+}