aboutsummaryrefslogtreecommitdiff
path: root/libjava/java
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2008-03-13 16:43:54 +0000
committerTom Tromey <tromey@gcc.gnu.org>2008-03-13 16:43:54 +0000
commit2599b56f41927c9122e457bb811dc89a10164d2b (patch)
tree3e00c86cfe961bb8b754069406dbd928045c1a31 /libjava/java
parent5f5f0635f1921f40de45c6783fe0c4e9b4c0d1ba (diff)
downloadgcc-2599b56f41927c9122e457bb811dc89a10164d2b.zip
gcc-2599b56f41927c9122e457bb811dc89a10164d2b.tar.gz
gcc-2599b56f41927c9122e457bb811dc89a10164d2b.tar.bz2
natClassLoader.cc (_Jv_RegisterInitiatingLoader): Check loading constraints.
* java/lang/natClassLoader.cc (_Jv_RegisterInitiatingLoader): Check loading constraints. (_Jv_CheckOrCreateLoadingConstraint): New function. * java/lang/ClassLoader.java (loadingConstraints): New field. * link.cc (_Jv_Linker::find_field): Use _Jv_CheckOrCreateLoadingConstraint. (_Jv_Linker::check_loading_constraints): New function. (_Jv_Linker::resolve_method_entry): Use check_loading_constraints. (_Jv_Linker::append_partial_itable): Likewise. (_Jv_Linker::layout_vtable_methods): Likewise. * include/jvm.h (_Jv_Linker::check_loading_constraints): Declare. (_Jv_CheckOrCreateLoadingConstraint): Declare. From-SVN: r133172
Diffstat (limited to 'libjava/java')
-rw-r--r--libjava/java/lang/ClassLoader.h1
-rw-r--r--libjava/java/lang/ClassLoader.java12
-rw-r--r--libjava/java/lang/natClassLoader.cc59
3 files changed, 69 insertions, 3 deletions
diff --git a/libjava/java/lang/ClassLoader.h b/libjava/java/lang/ClassLoader.h
index ed6f544..5112eab 100644
--- a/libjava/java/lang/ClassLoader.h
+++ b/libjava/java/lang/ClassLoader.h
@@ -86,6 +86,7 @@ private:
void checkInitialized();
public: // actually package-private
::java::util::HashMap * __attribute__((aligned(__alignof__( ::java::lang::Object)))) loadedClasses;
+ ::java::util::HashMap * loadingConstraints;
::java::util::HashMap * definedPackages;
private:
::java::lang::ClassLoader * parent;
diff --git a/libjava/java/lang/ClassLoader.java b/libjava/java/lang/ClassLoader.java
index 4682dbb..e0463ac 100644
--- a/libjava/java/lang/ClassLoader.java
+++ b/libjava/java/lang/ClassLoader.java
@@ -1,5 +1,5 @@
/* ClassLoader.java -- responsible for loading classes into the VM
- Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,6 +45,7 @@ import gnu.java.util.EmptyEnumeration;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.ref.WeakReference;
import java.net.URL;
import java.nio.ByteBuffer;
import java.security.CodeSource;
@@ -130,6 +131,15 @@ public abstract class ClassLoader
final HashMap loadedClasses = new HashMap();
/**
+ * Loading constraints registered with this classloader. This maps
+ * a class name to a weak reference to a class. When the reference
+ * is non-null, it means that a reference to the name must resolve
+ * to the indicated class.
+ */
+ final HashMap<String, WeakReference<Class>> loadingConstraints
+ = new HashMap<String, WeakReference<Class>>();
+
+ /**
* All packages defined by this classloader. It is not private in order to
* allow native code (and trusted subclasses) access to this field.
*/
diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc
index 9a687ff..fac1e4d 100644
--- a/libjava/java/lang/natClassLoader.cc
+++ b/libjava/java/lang/natClassLoader.cc
@@ -1,6 +1,6 @@
// natClassLoader.cc - Implementation of java.lang.ClassLoader native methods.
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008 Free Software Foundation
This file is part of libgcj.
@@ -41,6 +41,7 @@ details. */
#include <java/lang/StringBuffer.h>
#include <java/io/Serializable.h>
#include <java/lang/Cloneable.h>
+#include <java/lang/ref/WeakReference.h>
#include <java/util/HashMap.h>
#include <gnu/gcj/runtime/BootClassLoader.h>
#include <gnu/gcj/runtime/SystemClassLoader.h>
@@ -143,7 +144,21 @@ _Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
// them later.
return;
}
- loader->loadedClasses->put(klass->name->toString(), klass);
+
+ JvSynchronize sync (loader->loadingConstraints);
+
+ using namespace java::lang::ref;
+
+ jstring name = klass->getName();
+ WeakReference *ref = (WeakReference *) loader->loadingConstraints->get (name);
+ if (ref)
+ {
+ jclass constraint = (jclass) ref->get();
+ if (constraint && constraint != klass)
+ throw new java::lang::LinkageError(JvNewStringLatin1("loading constraint violated"));
+ }
+ loader->loadingConstraints->put(name, new WeakReference(klass));
+ loader->loadedClasses->put(name, klass);
}
// If we found an error while defining an interpreted class, we must
@@ -156,6 +171,46 @@ _Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
loader->loadedClasses->remove(klass->name->toString());
}
+// Check a loading constraint. In particular check that, if there is
+// a constraint for the name of KLASS in LOADER, that it maps to
+// KLASS. If there is no such constraint, make a new one. If the
+// constraint is violated, throw an exception. Do nothing for
+// primitive types.
+void
+_Jv_CheckOrCreateLoadingConstraint (jclass klass,
+ java::lang::ClassLoader *loader)
+{
+ // Strip arrays.
+ while (klass->isArray())
+ klass = klass->getComponentType();
+ // Ignore primitive types.
+ if (klass->isPrimitive())
+ return;
+
+ if (! loader)
+ loader = java::lang::VMClassLoader::bootLoader;
+ jstring name = klass->getName();
+
+ JvSynchronize sync (loader->loadingConstraints);
+
+ using namespace java::lang::ref;
+
+ WeakReference *ref = (WeakReference *) loader->loadingConstraints->get (name);
+ if (ref)
+ {
+ jclass constraint = (jclass) ref->get();
+ if (constraint)
+ {
+ if (klass != constraint)
+ throw new java::lang::LinkageError(JvNewStringLatin1("loading constraint violated"));
+ // Otherwise, all is ok.
+ return;
+ }
+ }
+ // No constraint (or old constraint GC'd). Make a new one.
+ loader->loadingConstraints->put(name, new WeakReference(klass));
+}
+
// Class registration.
//