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
This commit is contained in:
Tom Tromey 2008-03-13 16:43:54 +00:00 committed by Tom Tromey
parent 5f5f0635f1
commit 2599b56f41
8 changed files with 123 additions and 44 deletions

View file

@ -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;

View file

@ -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;
@ -129,6 +130,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.

View file

@ -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.
//