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

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