PR libgcj/12016, PR libgcj/18405, PR libgcj/17738:
* java/lang/Package.java (getPackages): Use VMClassLoader when appropriate. (getPackage): Likewise. * prims.cc (_Jv_CreateJavaVM): Call _Jv_RegisterBootstrapPackages. * include/jvm.h (_Jv_RegisterBootstrapPackages): Declare. * java/lang/VMClassLoader.java (getPackage): Rewrote. (getPackages): Likewise. (definedPackages): New field. (definePackageForNative): New method. * java/lang/Class.h (_Jv_FindClassInCache): Updated. * java/lang/natVMClassLoader.cc (loadClass): Updated. * defineclass.cc (handleClassBegin): Use ClassLoader.findLoadedClass. * java/lang/natClassLoader.cc (_Jv_RegisterInitiatingLoader): Rewrote. (struct _Jv_LoaderInfo): Removed. (initiated_classes): Likewise. (_Jv_UnregisterClass): Don't use initiated_classes. (_Jv_FindClassInCache): Likewise. Removed 'loader' argument. (_Jv_FindClass): Register classes found during boostrap. (BOOTSTRAP_CLASS_LIST_SIZE): New define. (bootstrap_class_list): New global. (bootstrap_index): Likewise. (_Jv_RegisterBootstrapPackages): New function. * gnu/gcj/runtime/natVMClassLoader.cc (findClass): Call definePackageForNative. (findClass): Updated. * gnu/gcj/runtime/VMClassLoader.java (definePackageForNative): New method. From-SVN: r93155
This commit is contained in:
parent
2f2bc52472
commit
3fd8010046
11 changed files with 159 additions and 106 deletions
|
@ -1,3 +1,37 @@
|
||||||
|
2005-01-10 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
PR libgcj/12016, PR libgcj/18405, PR libgcj/17738:
|
||||||
|
* java/lang/Package.java (getPackages): Use VMClassLoader when
|
||||||
|
appropriate.
|
||||||
|
(getPackage): Likewise.
|
||||||
|
* prims.cc (_Jv_CreateJavaVM): Call
|
||||||
|
_Jv_RegisterBootstrapPackages.
|
||||||
|
* include/jvm.h (_Jv_RegisterBootstrapPackages): Declare.
|
||||||
|
* java/lang/VMClassLoader.java (getPackage): Rewrote.
|
||||||
|
(getPackages): Likewise.
|
||||||
|
(definedPackages): New field.
|
||||||
|
(definePackageForNative): New method.
|
||||||
|
* java/lang/Class.h (_Jv_FindClassInCache): Updated.
|
||||||
|
* java/lang/natVMClassLoader.cc (loadClass): Updated.
|
||||||
|
* defineclass.cc (handleClassBegin): Use
|
||||||
|
ClassLoader.findLoadedClass.
|
||||||
|
* java/lang/natClassLoader.cc (_Jv_RegisterInitiatingLoader):
|
||||||
|
Rewrote.
|
||||||
|
(struct _Jv_LoaderInfo): Removed.
|
||||||
|
(initiated_classes): Likewise.
|
||||||
|
(_Jv_UnregisterClass): Don't use initiated_classes.
|
||||||
|
(_Jv_FindClassInCache): Likewise. Removed 'loader' argument.
|
||||||
|
(_Jv_FindClass): Register classes found during boostrap.
|
||||||
|
(BOOTSTRAP_CLASS_LIST_SIZE): New define.
|
||||||
|
(bootstrap_class_list): New global.
|
||||||
|
(bootstrap_index): Likewise.
|
||||||
|
(_Jv_RegisterBootstrapPackages): New function.
|
||||||
|
* gnu/gcj/runtime/natVMClassLoader.cc (findClass): Call
|
||||||
|
definePackageForNative.
|
||||||
|
(findClass): Updated.
|
||||||
|
* gnu/gcj/runtime/VMClassLoader.java (definePackageForNative):
|
||||||
|
New method.
|
||||||
|
|
||||||
2005-01-10 Tom Tromey <tromey@redhat.com>
|
2005-01-10 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
PR libgcj/18868:
|
PR libgcj/18868:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// defineclass.cc - defining a class from .class format.
|
// defineclass.cc - defining a class from .class format.
|
||||||
|
|
||||||
/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
|
/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
|
||||||
|
|
||||||
This file is part of libgcj.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -868,7 +868,7 @@ _Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_c
|
||||||
// was ClassLoader.defineClass called with an expected class name?
|
// was ClassLoader.defineClass called with an expected class name?
|
||||||
if (def->name == 0)
|
if (def->name == 0)
|
||||||
{
|
{
|
||||||
jclass orig = _Jv_FindClassInCache (loadedName, def->loader);
|
jclass orig = def->loader->findLoadedClass(loadedName->toString());
|
||||||
|
|
||||||
if (orig == 0)
|
if (orig == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation
|
/* Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
|
||||||
|
|
||||||
This file is part of libgcj.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -118,6 +118,27 @@ public final class VMClassLoader extends java.net.URLClassLoader
|
||||||
instance.init();
|
instance.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Define a package for something loaded natively.
|
||||||
|
void definePackageForNative(String className)
|
||||||
|
{
|
||||||
|
int lastDot = className.lastIndexOf('.');
|
||||||
|
if (lastDot != -1)
|
||||||
|
{
|
||||||
|
String packageName = className.substring(0, lastDot);
|
||||||
|
if (getPackage(packageName) == null)
|
||||||
|
{
|
||||||
|
// FIXME: this assumes we're defining the core, which
|
||||||
|
// isn't necessarily so. We could detect this and set up
|
||||||
|
// appropriately. We could also look at a manifest file
|
||||||
|
// compiled into the .so.
|
||||||
|
definePackage(packageName, "Java Platform API Specification",
|
||||||
|
"GNU", "1.4", "gcj", "GNU",
|
||||||
|
null, // FIXME: gcj version.
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This keeps track of shared libraries we've already tried to load.
|
// This keeps track of shared libraries we've already tried to load.
|
||||||
private HashSet tried_libraries = new HashSet();
|
private HashSet tried_libraries = new HashSet();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Native code for VMClassLoader
|
// Native code for VMClassLoader
|
||||||
|
|
||||||
/* Copyright (C) 2002, 2003 Free Software Foundation
|
/* Copyright (C) 2002, 2003, 2005 Free Software Foundation
|
||||||
|
|
||||||
This file is part of libgcj.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ jclass
|
||||||
gnu::gcj::runtime::VMClassLoader::findClass (jstring name)
|
gnu::gcj::runtime::VMClassLoader::findClass (jstring name)
|
||||||
{
|
{
|
||||||
_Jv_Utf8Const *name_u = _Jv_makeUtf8Const (name);
|
_Jv_Utf8Const *name_u = _Jv_makeUtf8Const (name);
|
||||||
jclass klass = _Jv_FindClassInCache (name_u, 0);
|
jclass klass = _Jv_FindClassInCache (name_u);
|
||||||
|
|
||||||
if (! klass && lib_control != LIB_NEVER)
|
if (! klass && lib_control != LIB_NEVER)
|
||||||
{
|
{
|
||||||
|
@ -65,12 +65,14 @@ gnu::gcj::runtime::VMClassLoader::findClass (jstring name)
|
||||||
so_base_name = so_base_name->substring (0, nd);
|
so_base_name = so_base_name->substring (0, nd);
|
||||||
|
|
||||||
if (loaded)
|
if (loaded)
|
||||||
klass = _Jv_FindClassInCache (name_u, 0);
|
klass = _Jv_FindClassInCache (name_u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now try loading using the interpreter.
|
// Either define the package, or try loading using the interpreter.
|
||||||
if (! klass)
|
if (klass)
|
||||||
|
definePackageForNative(name);
|
||||||
|
else
|
||||||
klass = java::net::URLClassLoader::findClass (name);
|
klass = java::net::URLClassLoader::findClass (name);
|
||||||
|
|
||||||
return klass;
|
return klass;
|
||||||
|
|
|
@ -561,4 +561,6 @@ extern void (*_Jv_JVMPI_Notify_THREAD_END) (JVMPI_Event *event);
|
||||||
/* FIXME: this should really be defined in some more generic place */
|
/* FIXME: this should really be defined in some more generic place */
|
||||||
#define ROUND(V, A) (((((unsigned) (V))-1) | ((A)-1))+1)
|
#define ROUND(V, A) (((((unsigned) (V))-1) | ((A)-1))+1)
|
||||||
|
|
||||||
|
extern void _Jv_RegisterBootstrapPackages ();
|
||||||
|
|
||||||
#endif /* __JAVA_JVM_H__ */
|
#endif /* __JAVA_JVM_H__ */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Class.h - Header file for java.lang.Class. -*- c++ -*-
|
// Class.h - Header file for java.lang.Class. -*- c++ -*-
|
||||||
|
|
||||||
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
|
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
|
||||||
|
|
||||||
This file is part of libgcj.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -215,8 +215,7 @@ void _Jv_RegisterInitiatingLoader (jclass,java::lang::ClassLoader*);
|
||||||
void _Jv_UnregisterClass (jclass);
|
void _Jv_UnregisterClass (jclass);
|
||||||
jclass _Jv_FindClass (_Jv_Utf8Const *name,
|
jclass _Jv_FindClass (_Jv_Utf8Const *name,
|
||||||
java::lang::ClassLoader *loader);
|
java::lang::ClassLoader *loader);
|
||||||
jclass _Jv_FindClassInCache (_Jv_Utf8Const *name,
|
jclass _Jv_FindClassInCache (_Jv_Utf8Const *name);
|
||||||
java::lang::ClassLoader *loader);
|
|
||||||
jclass _Jv_PopClass (void);
|
jclass _Jv_PopClass (void);
|
||||||
void _Jv_PushClass (jclass k);
|
void _Jv_PushClass (jclass k);
|
||||||
void _Jv_NewArrayClass (jclass element,
|
void _Jv_NewArrayClass (jclass element,
|
||||||
|
@ -440,8 +439,7 @@ private:
|
||||||
friend void ::_Jv_UnregisterClass (jclass);
|
friend void ::_Jv_UnregisterClass (jclass);
|
||||||
friend jclass (::_Jv_FindClass) (_Jv_Utf8Const *name,
|
friend jclass (::_Jv_FindClass) (_Jv_Utf8Const *name,
|
||||||
java::lang::ClassLoader *loader);
|
java::lang::ClassLoader *loader);
|
||||||
friend jclass (::_Jv_FindClassInCache) (_Jv_Utf8Const *name,
|
friend jclass (::_Jv_FindClassInCache) (_Jv_Utf8Const *name);
|
||||||
java::lang::ClassLoader *loader);
|
|
||||||
friend jclass (::_Jv_PopClass) (void);
|
friend jclass (::_Jv_PopClass) (void);
|
||||||
friend void ::_Jv_PushClass (jclass k);
|
friend void ::_Jv_PushClass (jclass k);
|
||||||
friend void ::_Jv_NewArrayClass (jclass element,
|
friend void ::_Jv_NewArrayClass (jclass element,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Package.java -- information about a package
|
/* Package.java -- information about a package
|
||||||
Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
Copyright (C) 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GNU Classpath.
|
This file is part of GNU Classpath.
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ public class Package
|
||||||
{
|
{
|
||||||
// Get the caller's classloader
|
// Get the caller's classloader
|
||||||
ClassLoader cl = VMSecurityManager.currentClassLoader();
|
ClassLoader cl = VMSecurityManager.currentClassLoader();
|
||||||
return cl != null ? cl.getPackage(name) : null;
|
return cl != null ? cl.getPackage(name) : VMClassLoader.getPackage(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -288,10 +288,7 @@ public class Package
|
||||||
// Get the caller's classloader
|
// Get the caller's classloader
|
||||||
Class c = VMSecurityManager.getClassContext()[1];
|
Class c = VMSecurityManager.getClassContext()[1];
|
||||||
ClassLoader cl = c.getClassLoader();
|
ClassLoader cl = c.getClassLoader();
|
||||||
// Sun's implementation returns the packages loaded by the bootstrap
|
return cl != null ? cl.getPackages() : VMClassLoader.getPackages();
|
||||||
// classloader if cl is null, but right now our bootstrap classloader
|
|
||||||
// does not create any Packages.
|
|
||||||
return cl != null ? cl.getPackages() : new Package[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* VMClassLoader.java -- Reference implementation of native interface
|
/* VMClassLoader.java -- Reference implementation of native interface
|
||||||
required by ClassLoader
|
required by ClassLoader
|
||||||
Copyright (C) 1998, 2001, 2002, 2003, 2004 Free Software Foundation
|
Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
|
||||||
|
|
||||||
This file is part of GNU Classpath.
|
This file is part of GNU Classpath.
|
||||||
|
|
||||||
|
@ -76,6 +76,8 @@ final class VMClassLoader
|
||||||
unknownProtectionDomain = new ProtectionDomain(null, permissions);
|
unknownProtectionDomain = new ProtectionDomain(null, permissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final HashMap definedPackages = new HashMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to define a class using a string of bytes. This assumes that
|
* Helper to define a class using a string of bytes. This assumes that
|
||||||
* the security checks have already been performed, if necessary.
|
* the security checks have already been performed, if necessary.
|
||||||
|
@ -173,9 +175,9 @@ final class VMClassLoader
|
||||||
* @param name the name to find
|
* @param name the name to find
|
||||||
* @return the named package, if it exists
|
* @return the named package, if it exists
|
||||||
*/
|
*/
|
||||||
static Package getPackage(String name)
|
static synchronized Package getPackage(String name)
|
||||||
{
|
{
|
||||||
return null;
|
return (Package) definedPackages.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -185,9 +187,33 @@ final class VMClassLoader
|
||||||
*
|
*
|
||||||
* @return all named packages, if any exist
|
* @return all named packages, if any exist
|
||||||
*/
|
*/
|
||||||
static Package[] getPackages()
|
static synchronized Package[] getPackages()
|
||||||
{
|
{
|
||||||
return new Package[0];
|
Package[] packages = new Package[definedPackages.size()];
|
||||||
|
return (Package[]) definedPackages.values().toArray(packages);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define a package for something loaded natively.
|
||||||
|
static synchronized void definePackageForNative(String className)
|
||||||
|
{
|
||||||
|
int lastDot = className.lastIndexOf('.');
|
||||||
|
if (lastDot != -1)
|
||||||
|
{
|
||||||
|
String packageName = className.substring(0, lastDot);
|
||||||
|
if (getPackage(packageName) == null)
|
||||||
|
{
|
||||||
|
// FIXME: this assumes we're defining the core, which
|
||||||
|
// isn't necessarily so. We could detect this and set up
|
||||||
|
// appropriately. We could also look at a manifest file
|
||||||
|
// compiled into the .so.
|
||||||
|
Package p = new Package(packageName,
|
||||||
|
"Java Platform API Specification",
|
||||||
|
"GNU", "1.4", "gcj", "GNU",
|
||||||
|
null, // FIXME: gcj version.
|
||||||
|
null);
|
||||||
|
definedPackages.put(packageName, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// natClassLoader.cc - Implementation of java.lang.ClassLoader native methods.
|
// natClassLoader.cc - Implementation of java.lang.ClassLoader native methods.
|
||||||
|
|
||||||
/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
|
/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
|
||||||
|
|
||||||
This file is part of libgcj.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -42,19 +42,7 @@ details. */
|
||||||
#include <java/lang/StringBuffer.h>
|
#include <java/lang/StringBuffer.h>
|
||||||
#include <java/io/Serializable.h>
|
#include <java/io/Serializable.h>
|
||||||
#include <java/lang/Cloneable.h>
|
#include <java/lang/Cloneable.h>
|
||||||
|
#include <java/util/HashMap.h>
|
||||||
//
|
|
||||||
// A single class can have many "initiating" class loaders,
|
|
||||||
// and a single "defining" class loader. The Defining
|
|
||||||
// class loader is what is returned from Class.getClassLoader()
|
|
||||||
// and is used when loading dependent classes during resolution.
|
|
||||||
// The set of initiating class loaders are used to ensure
|
|
||||||
// safety of linking, and is maintained in the hash table
|
|
||||||
// "initiated_classes". A defining classloader is by definition also
|
|
||||||
// initiating, so we only store classes in this table if they have more
|
|
||||||
// than one class loader associated.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
// Size of local hash table.
|
// Size of local hash table.
|
||||||
#define HASH_LEN 1013
|
#define HASH_LEN 1013
|
||||||
|
@ -62,56 +50,37 @@ details. */
|
||||||
// Hash function for Utf8Consts.
|
// Hash function for Utf8Consts.
|
||||||
#define HASH_UTF(Utf) ((Utf)->hash16() % HASH_LEN)
|
#define HASH_UTF(Utf) ((Utf)->hash16() % HASH_LEN)
|
||||||
|
|
||||||
struct _Jv_LoaderInfo
|
|
||||||
{
|
|
||||||
_Jv_LoaderInfo *next;
|
|
||||||
java::lang::Class *klass;
|
|
||||||
java::lang::ClassLoader *loader;
|
|
||||||
};
|
|
||||||
|
|
||||||
static _Jv_LoaderInfo *initiated_classes[HASH_LEN];
|
|
||||||
static jclass loaded_classes[HASH_LEN];
|
static jclass loaded_classes[HASH_LEN];
|
||||||
|
|
||||||
// This is the root of a linked list of classes
|
// This is the root of a linked list of classes
|
||||||
static jclass stack_head;
|
static jclass stack_head;
|
||||||
|
|
||||||
|
// While bootstrapping we keep a list of classes we found, so that we
|
||||||
|
// can register their packages. There aren't many of these so we
|
||||||
|
// just keep a small buffer here and abort if we overflow.
|
||||||
|
#define BOOTSTRAP_CLASS_LIST_SIZE 20
|
||||||
|
static jclass bootstrap_class_list[BOOTSTRAP_CLASS_LIST_SIZE];
|
||||||
|
static int bootstrap_index;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This tries to find a class in our built-in cache. This cache is
|
||||||
|
// used only for classes which are linked in to the executable or
|
||||||
|
// loaded via dlopen().
|
||||||
jclass
|
jclass
|
||||||
_Jv_FindClassInCache (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
|
_Jv_FindClassInCache (_Jv_Utf8Const *name)
|
||||||
{
|
{
|
||||||
JvSynchronize sync (&java::lang::Class::class$);
|
JvSynchronize sync (&java::lang::Class::class$);
|
||||||
jint hash = HASH_UTF (name);
|
jint hash = HASH_UTF (name);
|
||||||
|
|
||||||
if (loader && loader == java::lang::ClassLoader::getSystemClassLoader())
|
|
||||||
loader = NULL;
|
|
||||||
|
|
||||||
// first, if LOADER is a defining loader, then it is also initiating
|
|
||||||
jclass klass;
|
jclass klass;
|
||||||
for (klass = loaded_classes[hash]; klass; klass = klass->next)
|
for (klass = loaded_classes[hash]; klass; klass = klass->next)
|
||||||
{
|
{
|
||||||
if (loader == klass->loader && _Jv_equalUtf8Consts (name, klass->name))
|
if (_Jv_equalUtf8Consts (name, klass->name))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, it may be that the class in question was defined
|
|
||||||
// by some other loader, but that the loading was initiated by
|
|
||||||
// the loader in question.
|
|
||||||
if (!klass)
|
|
||||||
{
|
|
||||||
_Jv_LoaderInfo *info;
|
|
||||||
for (info = initiated_classes[hash]; info; info = info->next)
|
|
||||||
{
|
|
||||||
if (loader == info->loader
|
|
||||||
&& _Jv_equalUtf8Consts (name, info->klass->name))
|
|
||||||
{
|
|
||||||
klass = info->klass;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return klass;
|
return klass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,38 +99,15 @@ _Jv_UnregisterClass (jclass the_class)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_Jv_LoaderInfo **info = &(initiated_classes[hash]);
|
|
||||||
for ( ; ; info = &((*info)->next))
|
|
||||||
{
|
|
||||||
while (*info && (*info)->klass == the_class)
|
|
||||||
{
|
|
||||||
_Jv_LoaderInfo *old = *info;
|
|
||||||
*info = (*info)->next;
|
|
||||||
_Jv_Free (old);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*info == NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register an initiating class loader for a given class.
|
||||||
void
|
void
|
||||||
_Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
|
_Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
|
||||||
{
|
{
|
||||||
if (loader && loader == java::lang::ClassLoader::getSystemClassLoader())
|
if (! loader)
|
||||||
loader = NULL;
|
loader = java::lang::ClassLoader::getSystemClassLoader();
|
||||||
|
loader->loadedClasses->put(klass->name->toString(), klass);
|
||||||
// This information can't be visible to the GC.
|
|
||||||
_Jv_LoaderInfo *info
|
|
||||||
= (_Jv_LoaderInfo *) _Jv_Malloc (sizeof(_Jv_LoaderInfo));
|
|
||||||
jint hash = HASH_UTF(klass->name);
|
|
||||||
|
|
||||||
JvSynchronize sync (&java::lang::Class::class$);
|
|
||||||
info->loader = loader;
|
|
||||||
info->klass = klass;
|
|
||||||
info->next = initiated_classes[hash];
|
|
||||||
initiated_classes[hash] = info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is called many times during startup, before main() is
|
// This function is called many times during startup, before main() is
|
||||||
|
@ -254,15 +200,21 @@ _Jv_RegisterClass (jclass klass)
|
||||||
jclass
|
jclass
|
||||||
_Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
|
_Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
|
||||||
{
|
{
|
||||||
jclass klass = _Jv_FindClassInCache (name, loader);
|
// See if the class was already loaded by this loader. This handles
|
||||||
|
// initiating loader checks, as we register classes with their
|
||||||
|
// initiating loaders.
|
||||||
|
java::lang::ClassLoader *sys
|
||||||
|
= java::lang::ClassLoader::getSystemClassLoader ();
|
||||||
|
java::lang::ClassLoader *real = loader;
|
||||||
|
if (! real)
|
||||||
|
real = sys;
|
||||||
|
jstring sname = name->toString();
|
||||||
|
// We might still be bootstrapping the VM, in which case there
|
||||||
|
// won't be a system class loader yet.
|
||||||
|
jclass klass = real ? real->findLoadedClass (sname) : NULL;
|
||||||
|
|
||||||
if (! klass)
|
if (! klass)
|
||||||
{
|
{
|
||||||
jstring sname = name->toString();
|
|
||||||
|
|
||||||
java::lang::ClassLoader *sys
|
|
||||||
= java::lang::ClassLoader::getSystemClassLoader ();
|
|
||||||
|
|
||||||
if (loader)
|
if (loader)
|
||||||
{
|
{
|
||||||
// Load using a user-defined loader, jvmspec 5.3.2
|
// Load using a user-defined loader, jvmspec 5.3.2
|
||||||
|
@ -277,7 +229,7 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
|
||||||
if (klass && klass->getClassLoaderInternal () != delegate)
|
if (klass && klass->getClassLoaderInternal () != delegate)
|
||||||
_Jv_RegisterInitiatingLoader (klass, loader);
|
_Jv_RegisterInitiatingLoader (klass, loader);
|
||||||
}
|
}
|
||||||
else
|
else if (sys)
|
||||||
{
|
{
|
||||||
// Load using the bootstrap loader jvmspec 5.3.1.
|
// Load using the bootstrap loader jvmspec 5.3.1.
|
||||||
klass = sys->loadClass (sname, false);
|
klass = sys->loadClass (sname, false);
|
||||||
|
@ -286,6 +238,15 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
|
||||||
if (klass)
|
if (klass)
|
||||||
_Jv_RegisterInitiatingLoader (klass, 0);
|
_Jv_RegisterInitiatingLoader (klass, 0);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Not even a bootstrap loader, try the built-in cache.
|
||||||
|
klass = _Jv_FindClassInCache (name);
|
||||||
|
|
||||||
|
if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE)
|
||||||
|
abort ();
|
||||||
|
bootstrap_class_list[bootstrap_index++] = klass;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -297,6 +258,13 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
|
||||||
return klass;
|
return klass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_Jv_RegisterBootstrapPackages ()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < bootstrap_index; ++i)
|
||||||
|
java::lang::VMClassLoader::definePackageForNative(bootstrap_class_list[i]->getName());
|
||||||
|
}
|
||||||
|
|
||||||
jclass
|
jclass
|
||||||
_Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
|
_Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
|
||||||
java::lang::ClassLoader *loader)
|
java::lang::ClassLoader *loader)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// natVMClassLoader.cc - VMClassLoader native methods
|
// natVMClassLoader.cc - VMClassLoader native methods
|
||||||
|
|
||||||
/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
|
/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
|
||||||
|
|
||||||
This file is part of libgcj.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ jclass
|
||||||
java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
|
java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
|
||||||
{
|
{
|
||||||
_Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
|
_Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
|
||||||
jclass klass = _Jv_FindClassInCache (utf, NULL);
|
jclass klass = _Jv_FindClassInCache (utf);
|
||||||
if (klass)
|
if (klass)
|
||||||
{
|
{
|
||||||
// We never want to return a class without its supers linked.
|
// We never want to return a class without its supers linked.
|
||||||
|
@ -140,6 +140,9 @@ java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
|
||||||
_Jv_InitClass (klass);
|
_Jv_InitClass (klass);
|
||||||
else
|
else
|
||||||
_Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
|
_Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
|
||||||
|
|
||||||
|
definePackageForNative(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return klass;
|
return klass;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// prims.cc - Code for core of runtime environment.
|
// prims.cc - Code for core of runtime environment.
|
||||||
|
|
||||||
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
|
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
|
||||||
|
|
||||||
This file is part of libgcj.
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
@ -968,6 +968,8 @@ _Jv_CreateJavaVM (void* /*vm_args*/)
|
||||||
// system loader, by having it read the class path.
|
// system loader, by having it read the class path.
|
||||||
gnu::gcj::runtime::VMClassLoader::initialize();
|
gnu::gcj::runtime::VMClassLoader::initialize();
|
||||||
|
|
||||||
|
_Jv_RegisterBootstrapPackages();
|
||||||
|
|
||||||
no_memory = new java::lang::OutOfMemoryError;
|
no_memory = new java::lang::OutOfMemoryError;
|
||||||
|
|
||||||
java::lang::VMThrowable::trace_enabled = 1;
|
java::lang::VMThrowable::trace_enabled = 1;
|
||||||
|
|
Loading…
Add table
Reference in a new issue