removed the class hash and all functions identifying classes by name only
authoredwin <none@none>
Sun, 3 Apr 2005 16:53:16 +0000 (16:53 +0000)
committeredwin <none@none>
Sun, 3 Apr 2005 16:53:16 +0000 (16:53 +0000)
22 files changed:
src/cacao/cacao.c
src/native/jni.c
src/native/native.c
src/native/vm/VMClass.c
src/native/vm/VMClassLoader.c
src/native/vm/VMStackWalker.c
src/native/vm/VMThread.c
src/threads/green/threads.c
src/vm/builtin.c
src/vm/class.c
src/vm/class.h
src/vm/classcache.c
src/vm/classcache.h
src/vm/jit/inline/parseXTA.c
src/vm/jit/parse.c
src/vm/jit/stacktrace.c
src/vm/jit/verify/typeinfo.c
src/vm/linker.c
src/vm/loader.c
src/vm/loader.h
src/vm/resolve.c
src/vm/tables.c

index b36508d7f0e84de627835ab68783d7d07568206a..b91195677ee5a43417daf2d20f97a5d0d641242c 100644 (file)
@@ -37,7 +37,7 @@
      - Calling the class loader
      - Running the main method
 
-   $Id: cacao.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: cacao.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -60,6 +60,7 @@
 #include "vm/statistics.h"
 #include "vm/stringlocal.h"
 #include "vm/tables.h"
+#include "vm/classcache.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 
@@ -919,32 +920,10 @@ int main(int argc, char **argv)
                        mainstring = getmainclassnamefromjar((JNIEnv *) &env, mainstring);
                }
 
-               /* get system classloader */
-
-               m = class_resolveclassmethod(class_java_lang_ClassLoader,
-                                                                        utf_new_char("getSystemClassLoader"),
-                                                                        utf_new_char("()Ljava/lang/ClassLoader;"),
-                                                                        class_java_lang_Object,
-                                                                        false);
-
-               cl = (classinfo *) asm_calljavafunction(m, NULL, NULL, NULL, NULL);
-
-               /* get `loadClass' method */
-
-               m = class_resolveclassmethod(cl->header.vftbl->class,
-                                                                        utf_loadClass,
-                                                                        utf_java_lang_String__java_lang_Class,
-                                                                        class_java_lang_Object,
-                                                                        false);
-
                /* load the main class */
 
-               mainclass =
-                       (classinfo *) asm_calljavafunction(m,
-                                                                                          cl,
-                                                                                          javastring_new_char(mainstring),
-                                                                                          NULL,
-                                                                                          NULL);
+               if (!load_class_from_sysloader(utf_new_char(mainstring),&mainclass))
+                       throw_main_exception_exit();
 
                /* error loading class, clear exceptionptr for new exception */
 
@@ -1024,31 +1003,41 @@ int main(int argc, char **argv)
                methodinfo *m;
                u4 slot;
                s4 i;
+               classcache_name_entry *nmen;
+               classcache_class_entry *clsen;
+               classcache_loader_entry *lden;
 
                /* create all classes found in the classpath */
                /* XXX currently only works with zip/jar's */
                create_all_classes();
 
-               /* load and link all classes */
-               for (slot = 0; slot < class_hash.size; slot++) {
-                       c = class_hash.ptr[slot];
-
-                       while (c) {
-                               assert(c->loaded);
-
-                               if (!c->linked)
-                                       if (!link_class(c))
-                                               throw_main_exception_exit();
-
-                               /* compile all class methods */
-                               for (i = 0; i < c->methodscount; i++) {
-                                       m = &(c->methods[i]);
-                                       if (m->jcode) {
-                                               (void) jit_compile(m);
+               /* link all classes */
+               for (slot=0; slot<classcache_hash.size; ++slot) {
+                       nmen = (classcache_name_entry *) classcache_hash.ptr[slot];
+                       for (; nmen; nmen=nmen->hashlink) {
+                               /* iterate over all class entries */
+                               for (clsen=nmen->classes; clsen; clsen=clsen->next) {
+                                       c = clsen->classobj;
+                                       if (!c)
+                                               continue;
+
+                                       assert(c);
+                                       assert(c->loaded);
+                                       /*utf_fprint_classname(stderr,c->name);fprintf(stderr,"\n");*/
+
+                                       if (!c->linked)
+                                               if (!link_class(c))
+                                                       throw_main_exception_exit();
+
+                                       /* compile all class methods */
+                                       for (i = 0; i < c->methodscount; i++) {
+                                               m = &(c->methods[i]);
+                                               if (m->jcode) {
+                                                       /*fprintf(stderr,"    compiling:");utf_fprint(stderr,m->name);fprintf(stderr,"\n");*/
+                                                       (void) jit_compile(m);
+                                               }
                                        }
                                }
-
-                               c = c->hashlink;
                        }
                }
        }
@@ -1060,7 +1049,7 @@ int main(int argc, char **argv)
                methodinfo *m;
 
                /* create, load and link the main class */
-               if (!load_class_bootstrap(utf_new_char(mainstring),&mainclass))
+               if (!load_class_from_sysloader(utf_new_char(mainstring),&mainclass))
                        throw_main_exception_exit();
 
                if (!link_class(mainclass))
index a4b995b80bebeb1a917fdae64d0b3a58a65a4fbc..c76f85af790781cc2c9cddfcf10dc56ec76c41b7 100644 (file)
@@ -31,7 +31,7 @@
             Martin Platter
             Christian Thalinger
 
-   $Id: jni.c 2194 2005-04-03 16:13:27Z twisti $
+   $Id: jni.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -616,11 +616,9 @@ jclass DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *b
 
 jclass FindClass(JNIEnv *env, const char *name)
 {
-       classinfo *c;  
+       classinfo *c = NULL;  
   
        if (!load_class_bootstrap(utf_new_char_classname((char *) name),&c) || !link_class(c)) {
-               class_remove(c);
-
                return NULL;
        }
 
@@ -3855,15 +3853,18 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
                java_objectheader *ivte;
 
                *exceptionptr = NULL;
-               ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
-               ivte = builtin_new(ivtec);
-               asm_calljavafunction(class_resolvemethod(ivtec,
-                                                                                                utf_new_char("<init>"),
-                                                                                                utf_new_char("(Ljava/lang/Throwable;)V")),
-                                                        ivte,
-                                                        exceptionToWrap,
-                                                        0,
-                                                        0);
+               if (load_class_bootstrap(utf_new_char("java/lang/reflect/InvocationTargetException"),
+                                                                &ivtec)) 
+               {
+                       ivte = builtin_new(ivtec);
+                       asm_calljavafunction(class_resolvemethod(ivtec,
+                                                                                                        utf_new_char("<init>"),
+                                                                                                        utf_new_char("(Ljava/lang/Throwable;)V")),
+                                                                ivte,
+                                                                exceptionToWrap,
+                                                                0,
+                                                                0);
+               }
 
                if (*exceptionptr != NULL)
                        panic("jni.c: error while creating InvocationTargetException wrapper");
index 40820dc329f4824efd0b6983f40ece52c2c37334..8437cb01bdcd48e425e8f570f13dbc05aae826a5 100644 (file)
@@ -30,7 +30,7 @@
 
    Changes: Christian Thalinger
 
-   $Id: native.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: native.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -797,8 +797,11 @@ java_objectarray *builtin_asm_createclasscontextarray(classinfo **end, classinfo
                }
        }
 
+       c = class_array_of(class_java_lang_Class,true);
+       if (!c)
+               return NULL;
        tmpArray = (java_objectarray*)
-               builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
+               builtin_newarray(size, c->vftbl);
 
        for(i = 0, current = start; i < size; i++, current--) {
                c = *current;
index b8a0d8201108f1fd82b683389c21cf9b294c1276..fcd446be2ad9ef3c6d155bcb25b5199de92de0df 100644 (file)
@@ -29,7 +29,7 @@
    Changes: Joseph Wenninger
             Christian Thalinger
 
-   $Id: VMClass.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: VMClass.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -86,13 +86,9 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, j
 
        u = javastring_toutf(s, true);
 
-       /* create a new class, ... */
-
-       c = class_new(u);
-
        /* try to load, ... */
 
-       if (!load_class_bootstrap(c)) {
+       if (!load_class_bootstrap(u,&c)) {
                classinfo *xclass;
 
                xclass = (*exceptionptr)->vftbl->class;
@@ -325,8 +321,8 @@ java_lang_reflect_Field* cacao_getField0(JNIEnv *env, java_lang_Class *that, jav
     int idx;
 
     /* create Field object */
-/*      c = (classinfo *) loader_load(utf_new_char("java/lang/reflect/Field")); */
-    c = class_new(utf_new_char("java/lang/reflect/Field"));
+       if (!load_class_bootstrap(utf_new_char("java/lang/reflect/Field"),&c))
+               return NULL;
     o = (java_lang_reflect_Field *) native_new_and_init(c);
 
     /* get fieldinfo entry */
@@ -381,10 +377,7 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredFields(JNI
                if ((c->fields[i].flags & ACC_PUBLIC) || (!public_only))
                        public_fields++;
 
-/*      class_field = loader_load(utf_new_char("java/lang/reflect/Field")); */
-    class_field = class_new(utf_new_char("java/lang/reflect/Field"));
-
-    if (!class_field) 
+       if (!load_class_bootstrap(utf_new_char("java/lang/reflect/Field"),&class_field))
                return NULL;
 
     /* create array of fields */
@@ -438,8 +431,8 @@ java_lang_reflect_Method* cacao_getMethod0(JNIEnv *env, java_lang_Class *that, j
     java_objectarray *exceptiontypes;    /* the exceptions thrown by the method */
     methodinfo *m;                      /* the method to be represented */
 
-/*      c = (classinfo *) loader_load(utf_new_char("java/lang/reflect/Method")); */
-    c = class_new(utf_new_char("java/lang/reflect/Method"));
+       if (!load_class_bootstrap(utf_new_char("java/lang/reflect/Method"),&c))
+               return NULL;
     o = (java_lang_reflect_Method *) native_new_and_init(c);
 
     /* find the method */
@@ -501,10 +494,7 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JN
     int pos = 0;
     int i;
 
-/*      class_method = (classinfo*) loader_load(utf_new_char ("java/lang/reflect/Method")); */
-    class_method = class_new(utf_new_char("java/lang/reflect/Method"));
-
-    if (!class_method) 
+       if (!load_class_bootstrap(utf_new_char ("java/lang/reflect/Method"),&class_method))
                return NULL;
 
        /* JOWENN: array classes do not declare methods according to mauve test. It should be considered, if 
@@ -818,13 +808,10 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_loadArrayClass(JNIEnv
 
        u = javastring_toutf(name, true);
 
-       /* class_new "loads" the array class */
-
-       c = class_new(u);
+       /* load the array class */
 
-       /* set the classloader */
-
-       c->classloader = (java_objectheader*) classloader; /* XXX is this correct? */
+       if (!load_class_from_classloader(u,(java_objectheader*)classloader,&c))
+               return NULL;
 
        use_class_as_object(c);
 
index 8316fc1bd3064a1bd4a158af068d85832e0ce4dd..b94a23917804ba9c2c50ca6df87b719de915db98 100644 (file)
@@ -29,7 +29,7 @@
    Changes: Joseph Wenninger
             Christian Thalinger
 
-   $Id: VMClassLoader.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: VMClassLoader.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -68,6 +68,7 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
        classinfo   *c;
        classinfo   *r;
        classbuffer *cb;
+       utf         *utfname;
 
        if ((off < 0) || (len < 0) || ((off + len) > buf->header.size)) {
                *exceptionptr =
@@ -83,12 +84,18 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
        }
 
        /* convert '.' to '/' in java string */
+       utfname = javastring_toutf(name, true);
+       
+       /* check if this class has already been defined */
+       c = classcache_lookup_defined((java_objectheader *)this,utfname);
+       if (c)
+               return c;
 
-       c = class_new(javastring_toutf(name, true));
+       /* create a new classinfo struct */
+       c = create_classinfo(utfname);
 
 #if defined(USE_THREADS)
        /* enter a monitor on the class */
-
        builtin_monitorenter((java_objectheader *) c);
 #endif
 
@@ -137,12 +144,9 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
        if (!r) {
                /* If return value is NULL, we had a problem and the class is not     */
                /* loaded. */
-
-               c->loaded = false;
-
                /* now free the allocated memory, otherwise we could ran into a DOS */
 
-               class_remove(c);
+               class_free(c);
 
                return NULL;
        }
index aefa632530c162264ac3cd83f17d9cc7748f664e..25dbbe19e2dac3675ba0aad5e68663673d9269fa 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: 
 
-   $Id: VMStackWalker.c 1919 2005-02-10 10:08:53Z twisti $
+   $Id: VMStackWalker.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -46,6 +46,7 @@
  */
 JNIEXPORT java_objectarray* JNICALL Java_gnu_classpath_VMStackWalker_getClassContext(JNIEnv *env, jclass clazz)
 {
+       classinfo *c;
        if (cacao_initializing)
                return 0;
 
@@ -54,7 +55,10 @@ JNIEXPORT java_objectarray* JNICALL Java_gnu_classpath_VMStackWalker_getClassCon
 #else
 
        /* XXX TWISTI: only a quick hack */
-       return (java_objectarray *) builtin_newarray(0, class_array_of(class_java_lang_Class)->vftbl);
+       c = class_array_of(class_java_lang_Class,true);
+       if (!c)
+               return NULL;
+       return (java_objectarray *) builtin_newarray(0, c->vftbl);
 #endif
 }
 
index e36b5729ccd9e88bd2e1c2cf5b2e7f89ed49b181..3cb90c50cd0eb2a0e75db15f66dc45f49765ee3c 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Joseph Wenninger
 
-   $Id: VMThread.c 1971 2005-03-01 20:06:36Z carolyn $
+   $Id: VMThread.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -78,6 +78,7 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMThread_countStackFrames(JNIEnv *env, java_
 JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv *env, jclass clazz)
 {
        java_lang_Thread *t;
+       classinfo *threadgroupclass;
 
        if (runverbose)
                log_text("java_lang_VMThread_currentThread called");
@@ -99,8 +100,10 @@ if (t == NULL) printf("t ptr is NULL\n"); fflush(stdout);
        if (runverbose)
                log_text("java_lang_VMThread_currentThread 222");
 
-               t->group = (java_lang_ThreadGroup *) 
-                       native_new_and_init(class_new(utf_new_char("java/lang/ThreadGroup")));
+       if (!load_class_bootstrap(utf_new_char("java/lang/ThreadGroup"),&threadgroupclass))
+               return NULL;
+
+       t->group = (java_lang_ThreadGroup *) native_new_and_init(threadgroupclass);
 
        if (runverbose)
                log_text("java_lang_VMThread_currentThread 333");
index 37c933aacc13d729c103cbd520ab8ee074971b50..2867ba5c8864e56ae2cfe68e74d568fd65db0407 100644 (file)
@@ -77,10 +77,10 @@ java_objectheader *init_vmthread(void *thr)
 {
         methodinfo *m;
         java_objectheader *o;
-       classinfo *c=class_new(utf_new_char("java/lang/VMThread"));
-
-        if (!c)
-                return *exceptionptr;
+               classinfo *c;
+               
+               if (!load_class_bootstrap(utf_new_char("java/lang/VMThread"),&c))
+                       return *exceptionptr;
 
         o = builtin_new(c);          /* create object          */
 
@@ -163,6 +163,7 @@ freeThreadStack (vmthread *vmtid)
 void
 initThreads(u1 *stackbottom)
 {
+       classinfo *c;
        thread *the_main_thread;
     int i;
        char mainname[] = "main";
@@ -177,8 +178,10 @@ initThreads(u1 *stackbottom)
        }
 
     /* Allocate a thread to be the main thread */
+       if (!load_class_bootstrap(utf_new_char("java/lang/Thread"),&c))
+               panic("Could not load java/lang/Thread");
     liveThreads = the_main_thread = 
-        (thread *) builtin_new(class_new(utf_new_char("java/lang/Thread")));
+        (thread *) builtin_new(c);
     the_main_thread->vmThread=init_vmthread(the_main_thread);
     assert(the_main_thread != 0);
     
index 96e27545f9d3baa18b500d947db4d6135a1d040d..a49c15a92f9a97a580d01f9719afbde2c9bbff5e 100644 (file)
@@ -36,7 +36,7 @@
    calls instead of machine instructions, using the C calling
    convention.
 
-   $Id: builtin.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: builtin.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -780,6 +780,8 @@ java_arrayheader *builtin_newarray(s4 size, vftbl_t *arrayvftbl)
 
 java_objectarray *builtin_anewarray(s4 size, classinfo *component)
 {
+       classinfo *c;
+       
        /* is class loaded */
        assert(component->loaded);
 
@@ -788,7 +790,10 @@ java_objectarray *builtin_anewarray(s4 size, classinfo *component)
                if (!link_class(component))
                        return NULL;
 
-       return (java_objectarray *) builtin_newarray(size, class_array_of(component)->vftbl);
+       c = class_array_of(component,true);
+       if (!c)
+               return NULL;
+       return (java_objectarray *) builtin_newarray(size, c->vftbl);
 }
 
 
index d191532ae9fa2553ec030d5f8e6964e9ffdf949f..4810802a274f754f087253a01116ee2002f271c5 100644 (file)
@@ -30,7 +30,7 @@
             Andreas Krall
             Christian Thalinger
 
-   $Id: class.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: class.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -57,6 +57,7 @@
 #include "vm/tables.h"
 #include "vm/utf8.h"
 #include "vm/loader.h"
+#include "vm/classcache.h"
 
 
 /******************************************************************************/
@@ -76,8 +77,6 @@
 
 /* global variables ***********************************************************/
 
-hashtable class_hash;                   /* hashtable for classes              */
-
 list unlinkedclasses;                   /* this is only used for eager class  */
                                         /* loading                            */
 
@@ -126,106 +125,9 @@ classinfo *pseudo_class_Arraystub = NULL;
 classinfo *pseudo_class_Null = NULL;
 classinfo *pseudo_class_New = NULL;
 
-/* class_new *******************************************************************
-
-   Searches for the class with the specified name in the classes
-   hashtable, if there is no such class a new classinfo structure is
-   created and inserted into the list of classes to be loaded.
-
-*******************************************************************************/
-
-classinfo *class_new(utf *classname)
-{
-    classinfo *c;
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-    tables_lock();
-#endif
-
-       /* we support eager class loading and linking on demand */
-       if (opt_eager) {
-               classinfo *tc;
-               classinfo *tmp;
-
-               list_init(&unlinkedclasses, OFFSET(classinfo, listnode));
-
-               if (!load_class_bootstrap(classname,&c)) {
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-                       tables_unlock();
-#endif
-                       return NULL;
-               }
-
-               /* link all referenced classes */
-
-               tc = list_first(&unlinkedclasses);
-
-               while (tc) {
-                       /* skip the current loaded/linked class */
-                       if (tc != c) {
-                               if (!link_class(tc)) {
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-                                       tables_unlock();
-#endif
-                                       return c;
-                               }
-                       }
-
-                       /* we need a tmp variable here, because list_remove sets prev and
-                          next to NULL */
-                       tmp = list_next(&unlinkedclasses, tc);
-                       list_remove(&unlinkedclasses, tc);
-                       tc = tmp;
-               }
-
-               if (!c->linked) {
-                       if (!link_class(c)) {
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-                               tables_unlock();
-#endif
-                               return c;
-                       }
-               }
-       }
-       else {
-               c = class_new_intern(classname);
-       }
-
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-    tables_unlock();
-#endif
-
-    return c;
-}
-
-
-classinfo *class_new_intern(utf *classname)
+classinfo *create_classinfo(utf *classname)
 {
        classinfo *c;     /* hashtable element */
-       u4 key;           /* hashkey computed from classname */
-       u4 slot;          /* slot in hashtable */
-       u2 i;
-
-       key  = utf_hashkey(classname->text, classname->blength);
-       slot = key & (class_hash.size - 1);
-       c    = class_hash.ptr[slot];
-
-       /* search external hash chain for the class */
-       while (c) {
-               if (c->name->blength == classname->blength) {
-                       for (i = 0; i < classname->blength; i++)
-                               if (classname->text[i] != c->name->text[i]) goto nomatch;
-                                               
-                       /* class found in hashtable */
-                       return c;
-               }
-                       
-       nomatch:
-               c = c->hashlink; /* next element in external chain */
-       }
-
-       /* location in hashtable found, create new classinfo structure */
 
 #if defined(STATISTICS)
        if (opt_stat)
@@ -278,50 +180,8 @@ classinfo *class_new_intern(utf *classname)
        c->classloader = NULL;
        c->sourcefile = NULL;
        
-       /* insert class into the hashtable */
-       c->hashlink = class_hash.ptr[slot];
-       class_hash.ptr[slot] = c;
-
-       /* update number of hashtable-entries */
-       class_hash.entries++;
-
-       if (class_hash.entries > (class_hash.size * 2)) {
-
-               /* reorganization of hashtable, average length of 
-                  the external chains is approx. 2                */  
-
-               u4 i;
-               classinfo *c;
-               hashtable newhash;  /* the new hashtable */
-
-               /* create new hashtable, double the size */
-               init_hashtable(&newhash, class_hash.size * 2);
-               newhash.entries = class_hash.entries;
-
-               /* transfer elements to new hashtable */
-               for (i = 0; i < class_hash.size; i++) {
-                       c = (classinfo *) class_hash.ptr[i];
-                       while (c) {
-                               classinfo *nextc = c->hashlink;
-                               u4 slot = (utf_hashkey(c->name->text, c->name->blength)) & (newhash.size - 1);
-                                               
-                               c->hashlink = newhash.ptr[slot];
-                               newhash.ptr[slot] = c;
-
-                               c = nextc;
-                       }
-               }
-       
-               /* dispose old table */ 
-               MFREE(class_hash.ptr, void*, class_hash.size);
-               class_hash = newhash;
-       }
-
-       /* Array classes need further initialization. */
        if (c->name->text[0] == '[') {
                /* Array classes are not loaded from classfiles. */
-               c->loaded = true;
-               class_new_array(c);
                c->packagename = array_packagename;
 
        } else {
@@ -344,97 +204,6 @@ classinfo *class_new_intern(utf *classname)
        return c;
 }
 
-
-/* class_get *******************************************************************
-
-   Searches for the class with the specified name in the classes
-   hashtable if there is no such class NULL is returned.
-
-*******************************************************************************/
-
-classinfo *class_get(utf *classname)
-{
-       classinfo *c;  /* hashtable element */ 
-       u4 key;        /* hashkey computed from classname */   
-       u4 slot;       /* slot in hashtable */
-       u2 i;  
-
-       key  = utf_hashkey(classname->text, classname->blength);
-       slot = key & (class_hash.size-1);
-       c    = class_hash.ptr[slot];
-
-       /* search external hash-chain */
-       while (c) {
-               if (c->name->blength == classname->blength) {
-                       /* compare classnames */
-                       for (i = 0; i < classname->blength; i++) 
-                               if (classname->text[i] != c->name->text[i])
-                                       goto nomatch;
-
-                       /* class found in hashtable */                          
-                       return c;
-               }
-                       
-       nomatch:
-               c = c->hashlink;
-       }
-
-       /* class not found */
-       return NULL;
-}
-
-
-/* class_remove ****************************************************************
-
-   Removes the class entry wth the specified name in the classes
-   hashtable, furthermore the class' resources are freed if there is
-   no such class false is returned.
-
-*******************************************************************************/
-
-bool class_remove(classinfo *c)
-{
-       classinfo *tc;                      /* hashtable element                  */
-       classinfo *pc;
-       u4 key;                             /* hashkey computed from classname    */
-       u4 slot;                            /* slot in hashtable                  */
-       u2 i;  
-
-       key  = utf_hashkey(c->name->text, c->name->blength);
-       slot = key & (class_hash.size - 1);
-       tc   = class_hash.ptr[slot];
-       pc   = NULL;
-
-       /* search external hash-chain */
-       while (tc) {
-               if (tc->name->blength == c->name->blength) {
-                       
-                       /* compare classnames */
-                       for (i = 0; i < c->name->blength; i++)
-                               if (tc->name->text[i] != c->name->text[i])
-                                       goto nomatch;
-
-                       /* class found in hashtable */
-                       if (!pc)
-                               class_hash.ptr[slot] = tc->hashlink;
-                       else
-                               pc->hashlink = tc->hashlink;
-
-                       class_free(tc);
-
-                       return true;
-               }
-                       
-       nomatch:
-               pc = tc;
-               tc = tc->hashlink;
-       }
-
-       /* class not found */
-       return false;
-}
-
-
 /* class_freepool **************************************************************
 
        Frees all resources used by this classes Constant Pool.
@@ -541,6 +310,42 @@ void class_free(classinfo *c)
 /*     GCFREE(c); */
 }
 
+/* get_array_class *************************************************************
+
+   Returns the array class with the given name for the given classloader.
+
+*******************************************************************************/
+
+static classinfo *get_array_class(utf *name,java_objectheader *initloader,
+                                                                                       java_objectheader *defloader,bool link)
+{
+       classinfo *c;
+       
+       /* lookup this class in the classcache */
+       c = classcache_lookup(initloader,name);
+       if (c)
+               return c;
+       c = classcache_lookup_defined(defloader,name);
+       if (c)
+               return c;
+
+       /* we have to create it */
+       c = create_classinfo(name);
+       if (!load_newly_created_array(c,initloader))
+               return NULL;
+
+       CLASS_ASSERT(c);
+       CLASS_ASSERT(c->loaded);
+       CLASS_ASSERT(c->classloader == defloader);
+
+       if (link && !c->linked)
+               if (!link_class(c))
+                       return NULL;
+
+       CLASS_ASSERT(!link || c->linked);
+
+       return c;
+}
 
 /* class_array_of **************************************************************
 
@@ -549,11 +354,11 @@ void class_free(classinfo *c)
 
 *******************************************************************************/
 
-classinfo *class_array_of(classinfo *component)
+classinfo *class_array_of(classinfo *component,bool link)
 {
     s4 namelen;
     char *namebuf;
-       classinfo *c;
+       utf *arrayname;
 
     /* Assemble the array class name */
     namelen = component->name->blength;
@@ -575,17 +380,7 @@ classinfo *class_array_of(classinfo *component)
         namelen += 3;
     }
 
-       c = class_new(utf_new(namebuf, namelen));
-
-       /* load this class and link it */
-
-       c->loaded = true;
-
-       if (!c->linked)
-               if (!link_class(c))
-                       return NULL;
-
-    return c;
+       return get_array_class(utf_new(namebuf, namelen),component->classloader,component->classloader,link);
 }
 
 
@@ -596,7 +391,7 @@ classinfo *class_array_of(classinfo *component)
 
 *******************************************************************************/
 
-classinfo *class_multiarray_of(s4 dim, classinfo *element)
+classinfo *class_multiarray_of(s4 dim, classinfo *element,bool link)
 {
     s4 namelen;
     char *namebuf;
@@ -623,7 +418,7 @@ classinfo *class_multiarray_of(s4 dim, classinfo *element)
     }
        memset(namebuf, '[', dim);
 
-    return class_new(utf_new(namebuf, namelen));
+       return get_array_class(utf_new(namebuf, namelen),element->classloader,element->classloader,link);
 }
 
 /* class_lookup_classref *******************************************************
index 13702fb073b484a7bf3dcb5ada501b0c1cd9bbbd..03b24ed07a30e1e131b3a7b0c8798431c8db13a3 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: class.h 2193 2005-04-02 19:33:43Z edwin $
+   $Id: class.h 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -107,7 +107,6 @@ struct classinfo {                /* class structure                          */
        u2          innerclasscount;  /* number of inner classes                  */
        innerclassinfo *innerclass;
 
-       classinfo  *hashlink;         /* link for external hash chain             */
        bool        classvftbl;       /* has its own copy of the Class vtbl       */
 
        s4          classUsed;        /* 0= not used 1 = used   CO-RT             */
@@ -146,8 +145,6 @@ struct extra_classref {
 
 /* global variables ***********************************************************/
 
-extern hashtable class_hash;            /* hashtable for classes              */
-
 extern list unlinkedclasses;   /* this is only used for eager class loading   */
 
 
@@ -221,26 +218,17 @@ extern classinfo *pseudo_class_New;
 
 /* function prototypes ********************************************************/
 
-/* search for class and create it if not found */
-classinfo *class_new(utf *u);
-
-/* without locking (caller already holding lock*/
-classinfo *class_new_intern(utf *u);
-
-/* search for class in classtable */
-classinfo *class_get(utf *u);
-
-/* remove class from classtable */
-bool class_remove(classinfo *c);
+/* create a new classinfo struct */
+classinfo *create_classinfo(utf *u);
 
 /* frees all resources used by the class */
 void class_free(classinfo *);
 
 /* return an array class with the given component class */
-classinfo *class_array_of(classinfo *component);
+classinfo *class_array_of(classinfo *component,bool link);
 
 /* return an array class with the given dimension and element class */
-classinfo *class_multiarray_of(s4 dim, classinfo *element);
+classinfo *class_multiarray_of(s4 dim, classinfo *element,bool link);
 
 /* return a classref for the given class name */
 /* (does a linear search!)                    */
index 040e7b86a4fa8bdfb733191480631caeb59bcdb8..012cf5ebba7b370e834077e88d7404eb6e9464ce 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: classcache.c 2190 2005-04-02 10:07:44Z edwin $
+   $Id: classcache.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -79,7 +79,7 @@
 /* GLOBAL VARIABLES                                                           */
 /*============================================================================*/
 
-static hashtable classcache_hash;
+hashtable classcache_hash;
 
 /*============================================================================*/
 /*                                                                            */
@@ -360,6 +360,50 @@ found:
        return cls;
 }
 
+/* classcache_lookup_defined ***************************************************
+   Lookup a class with the given name and defining loader
+  
+   IN:
+       defloader........defining loader
+       classname........class name
+  
+   RETURN VALUE:
+       The return value is a pointer to the cached class object,
+       or NULL, if the class is not in the cache.
+   
+*******************************************************************************/
+
+classinfo * 
+classcache_lookup_defined(classloader *defloader,utf *classname)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsen;
+       classcache_loader_entry *lden;
+       classinfo *cls = NULL;
+
+       CLASSCACHE_LOCK();
+
+       en = classcache_lookup_name(classname);
+       
+       if (en) {
+               /* iterate over all class entries */
+               for (clsen=en->classes; clsen; clsen=clsen->next) {
+                       if (!clsen->classobj)
+                               continue;
+                       
+                       /* check if this entry has been defined by defloader */
+                       if (clsen->classobj->classloader == defloader) {
+                               cls = clsen->classobj;
+                               goto found;
+                       }
+               }
+       }
+found:
+       CLASSCACHE_UNLOCK();
+       return cls;
+}
+
 /* classcache_store ************************************************************
    
    Store a loaded class
@@ -385,6 +429,7 @@ classcache_store(classloader *initloader,classinfo *cls)
        classcache_loader_entry *lden;
 
        CLASSCACHE_ASSERT(cls);
+       CLASSCACHE_ASSERT(cls->loaded);
 
 #ifdef CLASSCACHE_VERBOSE
        fprintf(stderr,"classcache_store(%p,",initloader);
index 127e85bd8450f7aa5e75cc0921add15bb39bc08e..f7049e8b990c8321cb08356112f7ec6ea6b4684e 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: classcache.h 2181 2005-04-01 16:53:33Z edwin $
+   $Id: classcache.h 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -39,6 +39,7 @@
 #include <stdio.h>  /* for FILE */
 
 #include "vm/references.h"
+#include "vm/tables.h"
 
 
 /* forward declarations *******************************************************/
@@ -49,6 +50,10 @@ typedef struct classcache_loader_entry classcache_loader_entry;
 
 typedef java_objectheader classloader;
 
+/* global variables ***********************************************************/
+
+extern hashtable classcache_hash;
+
 /* structs ********************************************************************/
 
 
@@ -148,6 +153,22 @@ void classcache_free();
 
 classinfo * classcache_lookup(classloader *initloader,utf *classname);
 
+/* classcache_lookup_defined ***************************************************
+   Lookup a class with the given name and defining loader
+  
+   IN:
+       defloader........defining loader
+       classname........class name
+  
+   RETURN VALUE:
+       The return value is a pointer to the cached class object,
+       or NULL, if the class is not in the cache.
+   
+*******************************************************************************/
+
+classinfo * classcache_lookup_defined(classloader *defloader,utf *classname);
+
 /* classcache_store ************************************************************
    
    Store a loaded class
index f87f121a0311215bd56f85601acd0d8fa260af90..2ce6102ff888d2fa25ad1f53843892b11cba9e2d 100644 (file)
@@ -39,7 +39,7 @@ Now wondering if there is a memory corruption because XTA seems to finish ok
 
    Authors: Carolyn Oates
 
-   $Id: parseXTA.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: parseXTA.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -170,6 +170,8 @@ static classSetNode *descriptor2typesL(methodinfo *m)
        char *class; 
        char *desc;
        classSetNode *p=NULL;
+       classinfo *clsinfo;
+       
        if (debugInfo >= 1) {
                printf("In descriptor2typesL >>>\t"); fflush(stdout);
                utf_display(m->class->name); printf(".");
@@ -215,8 +217,10 @@ static classSetNode *descriptor2typesL(methodinfo *m)
                        class = strtok(desc,";");
                        desc = strtok(NULL,"\0");
                        /* get/save classinfo ptr */
-                       classtypes[pcount-1] = class_get(utf_new_char(class));
-                       p = addClassCone(p,  class_get(utf_new_char(class)));
+                       if (!load_class_bootstrap(utf_new_char(class),&clsinfo))
+                               panic("could not load class in descriptor2typesL");
+                       classtypes[pcount-1] = clsinfo;
+                       p = addClassCone(p, clsinfo);
                        if (debugInfo >= 1) {
                                printf("LParam#%i 's class type is: %s\n",pcount-1,class);fflush(stdout);
                                printf("Lclasstypes[%i]=",pcount-1);fflush(stdout);
@@ -231,8 +235,10 @@ static classSetNode *descriptor2typesL(methodinfo *m)
                                class = strtok(desc,";");
                                desc = strtok(NULL,"\0");
                                /* get/save classinfo ptr */
-                               classtypes[pcount-1] = class_get(utf_new_char(class));
-                               p= addClassCone(p,  class_get(utf_new_char(class)));
+                               if (!load_class_bootstrap(utf_new_char(class),&clsinfo))
+                                       panic("could not load class in descriptor2typesL");
+                               classtypes[pcount-1] = clsinfo;
+                               p= addClassCone(p, clsinfo);
                                if (debugInfo >= 1) {
                                        printf("[Param#%i 's class type is: %s\n",pcount-1,class);
                                        printf("[classtypes[%i]=",pcount-1);fflush(stdout);
@@ -277,7 +283,9 @@ static classSetNode *descriptor2typesL(methodinfo *m)
                          
                /* get class string */
                class = strtok(desc,";");
-               m->returnclass = class_get(utf_new_char(class));
+               if (!load_class_bootstrap(utf_new_char(class),&clsinfo))
+                       panic("could not load class in descriptor2typesL");
+               m->returnclass = clsinfo;
                if (m->returnclass == NULL) {
                        printf("class=<%s>\t",class); fflush(stdout);
                        panic ("return class not found");
@@ -728,7 +736,8 @@ bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
                                desc = MNEW(char, 256);
                                strcpy(desc,++utf_ptr);
                                cname = strtok(desc,";");
-                               class = class_get(utf_new_char(cname));
+                               if (!load_class_bootstrap(utf_new_char(cname),&class))
+                                       panic("could not load class in xtaAddFldClassTypeInfo");
                                fi->xta->fldClassType= class;    /* save field's type class ptr */      
                        } 
                }
index 95c55f4131841e884f47b66eb458e074bef70e76..5ac2e7231bc8c033b91780b643e87d9ccc6f7851 100644 (file)
@@ -30,7 +30,7 @@
             Edwin Steiner
             Joseph Wenninger
 
-   $Id: parse.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: parse.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -659,6 +659,7 @@ SHOWOPCODE(DEBUG4)
                        i = code_get_u2(p + 1,inline_env->method);
                        {
                                classinfo *component;
+                               classinfo *c;
                                constant_classref *cr =
                                        (constant_classref*) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
 
@@ -666,7 +667,10 @@ SHOWOPCODE(DEBUG4)
                                                        cr,resolveEager,true,&component))
                                        return NULL;
 
-                               LOADCONST_A_BUILTIN(class_array_of(component)->vftbl);
+                               c = class_array_of(component,true);
+                               if (!c)
+                                       return NULL;
+                               LOADCONST_A_BUILTIN(c->vftbl);
                                s_count++;
                                BUILTIN2(BUILTIN_newarray, TYPE_ADR, currentline);
                        }
index 2e9e1ed9b379c64e16b4e2e4cdce47deba64e352..52a7e20db8c67e3b1b3c08186d6cc818637b7e31 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: Joseph Wenninger
 
-   $Id: stacktrace.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: stacktrace.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -331,8 +331,11 @@ void classContextCollector(void **target, stackTraceBuffer *buffer) {
                 }
         }
 
+               c = class_array_of(class_java_lang_Class,true);
+               if (!c)
+                       panic("Could not create array class in classContextCollector");
         tmpArray =
-                builtin_newarray(targetSize, class_array_of(class_java_lang_Class)->vftbl);
+                builtin_newarray(targetSize, c->vftbl);
 
         for(i = 0, current = start; i < targetSize; i++, current++) {
                 if (current->method==0) { i--; continue;}
index 4f980395dd63482be3f6941bef9a0aaa129bae60..01e179a53d582f6779588f9578127af84b4a6c38 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: Edwin Steiner
 
-   $Id: typeinfo.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: typeinfo.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -834,6 +834,10 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
        }
        else {
                vftbl_t *comp;
+               
+               if (!srcarray->typeclass.cls->linked)
+                       if (!link_class(srcarray->typeclass.cls))
+                               panic("XXX could not link class");
 
                TYPEINFO_ASSERT(srcarray->typeclass.cls->vftbl);
                TYPEINFO_ASSERT(srcarray->typeclass.cls->vftbl->arraydesc);
@@ -1437,7 +1441,9 @@ return_simple:
                 elementclass.any = NULL;
             }
             else {
-                common.cls = class_multiarray_of(dimension,pseudo_class_Arraystub);
+                common.cls = class_multiarray_of(dimension,pseudo_class_Arraystub,true);
+                               if (!common.cls)
+                                       panic("XXX Coult not create array class");
                 elementtype = ARRAYTYPE_OBJECT;
                 elementclass.cls = pseudo_class_Arraystub;
             }
@@ -1458,8 +1464,11 @@ return_simple:
                 /* DEBUG */ /* log_text("finding resulting array class: "); */
                                if (IS_CLASSREF(elementclass))
                                        common.ref = class_get_classref_multiarray_of(dimension,elementclass.ref);
-                               else
-                                       common.cls = class_multiarray_of(dimension,elementclass.cls);
+                               else {
+                                       common.cls = class_multiarray_of(dimension,elementclass.cls,true);
+                                       if (!common.cls)
+                                               panic("XXX Coult not create array class");
+                               }
                 /* DEBUG */ /* utf_display(common->name); printf("\n"); */
             }
                        else {
@@ -1631,7 +1640,7 @@ typeinfo_inc_dimension(typeinfo *info)
         info->elementtype = ARRAYTYPE_OBJECT;
         info->elementclass = info->typeclass;
     }
-    info->typeclass = class_array_of(info->typeclass);
+    info->typeclass = class_array_of(info->typeclass,true);
 }
 #endif
 
index 3f1d4adb3ba9658fb582e809361ac542faefb5f5..9ecd64c55cd659f1e59833a15d19f7b373af44dc 100644 (file)
@@ -32,7 +32,7 @@
             Edwin Steiner
             Christian Thalinger
 
-   $Id: linker.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: linker.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -155,33 +155,38 @@ bool linker_init(void)
 
     /* pseudo class for Arraystubs (extends java.lang.Object) */
     
-    pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
+    pseudo_class_Arraystub = create_classinfo(utf_new_char("$ARRAYSTUB$"));
        pseudo_class_Arraystub->loaded = true;
     pseudo_class_Arraystub->super.cls = class_java_lang_Object;
     pseudo_class_Arraystub->interfacescount = 2;
     pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
     pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
     pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
+       if (!classcache_store(NULL,pseudo_class_Arraystub))
+               panic("could not cache pseudo_class_Arraystub");
 
     if (!link_class(pseudo_class_Arraystub))
                return false;
 
     /* pseudo class representing the null type */
     
-       pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
+       pseudo_class_Null = create_classinfo(utf_new_char("$NULL$"));
        pseudo_class_Null->loaded = true;
     pseudo_class_Null->super.cls = class_java_lang_Object;
+       if (!classcache_store(NULL,pseudo_class_Null))
+               panic("could not cache pseudo_class_Null");
 
        if (!link_class(pseudo_class_Null))
                return false;
 
     /* pseudo class representing new uninitialized objects */
     
-       pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
+       pseudo_class_New = create_classinfo(utf_new_char("$NEW$"));
        pseudo_class_New->loaded = true;
        pseudo_class_New->linked = true; /* XXX is this allright? */
        pseudo_class_New->super.cls = class_java_lang_Object;
-
+       if (!classcache_store(NULL,pseudo_class_New))
+               panic("could not cache pseudo_class_New");
 
        /* create classes representing primitive types */
 
@@ -215,12 +220,16 @@ static bool link_primitivetype_table(void)
                        continue;
                
                /* create primitive class */
-               c = class_new_intern(utf_new_char(primitivetype_table[i].name));
+               c = create_classinfo(utf_new_char(primitivetype_table[i].name));
                c->classUsed = NOTUSED; /* not used initially CO-RT */
                c->impldBy = NULL;
                
                /* prevent loader from loading primitive class */
                c->loaded = true;
+               if (!classcache_store(NULL,c)) {
+                       log_text("Could not cache primitive class");
+                       return false;
+               }
                if (!link_class(c))
                        return false;
 
@@ -235,9 +244,11 @@ static bool link_primitivetype_table(void)
 
                /* create the primitive array class */
                if (primitivetype_table[i].arrayname) {
-                       c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
+                       c = create_classinfo(utf_new_char(primitivetype_table[i].arrayname));
+                       if (!load_newly_created_array(c,NULL))
+                               return false;
                        primitivetype_table[i].arrayclass = c;
-                       c->loaded = true;
+                       assert(c->loaded);
                        if (!c->linked)
                                if (!link_class(c))
                                        return false;
@@ -260,6 +271,11 @@ classinfo *link_class(classinfo *c)
 {
        classinfo *r;
 
+       if (!c) {
+               *exceptionptr = new_nullpointerexception();
+               return NULL;
+       }
+
 #if defined(USE_THREADS)
        /* enter a monitor on the class */
 
@@ -735,22 +751,22 @@ static arraydescriptor *link_array(classinfo *c)
        switch (c->name->text[1]) {
        case '[':
                /* c is an array of arrays. */
-               comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
-               if (!comp)
-                       panic("Could not find component array class.");
+               if (!load_class_from_classloader(utf_new_intern(c->name->text + 1, namelen - 1),
+                                                                                c->classloader,&comp))
+                       return NULL;
                break;
 
        case 'L':
                /* c is an array of objects. */
-               comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
-               if (!comp)
-                       panic("Could not find component class.");
+               if (!load_class_from_classloader(utf_new_intern(c->name->text + 2, namelen - 3),
+                                                                                c->classloader,&comp))
+                       return NULL;
                break;
        }
 
        /* If the component type has not been linked, link it now */
+       assert(!comp || comp->loaded);
        if (comp && !comp->linked) {
-               assert(comp->loaded);
 
                if (!link_class(comp))
                        return NULL;
index 64afdf353313336e012a3dd2e9564351d5319aa0..5b59b3336819ed8e7df2ea0596e5b49ae021232b 100644 (file)
@@ -32,7 +32,7 @@
             Edwin Steiner
             Christian Thalinger
 
-   $Id: loader.c 2193 2005-04-02 19:33:43Z edwin $
+   $Id: loader.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
 #undef JOWENN_DEBUG1
 #undef JOWENN_DEBUG2
 
+#ifdef LOADER_VERBOSE
+static int loader_recursion = 0;
+#define LOADER_INDENT()   do { int i; for(i=0;i<loader_recursion;++i) fputs("    ",stderr); } while (0)
+#define LOADER_INC()  loader_recursion++
+#define LOADER_DEC()  loader_recursion--
+#else
+#define LOADER_INC()
+#define LOADER_DEC()
+#endif
+
 
 /********************************************************************
    list of classpath entries (either filesystem directories or 
@@ -495,6 +505,7 @@ void suck_init(char *classpath)
 void create_all_classes()
 {
        classpath_info *cpi;
+       classinfo *c;
 
        for (cpi = classpath_entries; cpi != 0; cpi = cpi->next) {
 #if defined(USE_ZLIB)
@@ -506,7 +517,7 @@ void create_all_classes()
                        ce = s->cacao_dir_list;
                                
                        while (ce) {
-                               (void) class_new(ce->name);
+                               load_class_bootstrap(ce->name,&c);
                                ce = ce->next;
                        }
 
@@ -1844,6 +1855,57 @@ static bool load_attributes(classbuffer *cb, u4 num)
        return true;
 }
 
+/* load_class_from_sysloader ***************************************************
+
+   Load the class with the given name using the system class loader
+
+   IN:
+       name.............the classname
+          
+
+   OUT:
+       *result..........set to the loaded class
+
+   RETURN VALUE:
+       true.............everything ok
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+bool load_class_from_sysloader(utf *name,classinfo **result)
+{
+       methodinfo *m;
+       java_objectheader *cl;
+       bool success;
+
+#ifdef LOADER_VERBOSE
+       LOADER_INDENT();
+       fprintf(stderr,"load_class_from_sysloader(");
+       utf_fprint(stderr,name);fprintf(stderr,")\n");
+#endif
+
+       LOADER_ASSERT(class_java_lang_Object);
+       LOADER_ASSERT(class_java_lang_ClassLoader);
+       LOADER_ASSERT(class_java_lang_ClassLoader->linked);
+       
+       m = class_resolveclassmethod(class_java_lang_ClassLoader,
+                                                                utf_new_char("getSystemClassLoader"), /* XXX use variable */
+                                                                utf_new_char("()Ljava/lang/ClassLoader;"), /* XXX use variable */
+                                                                class_java_lang_Object,
+                                                                false);
+
+       if (!m)
+               return false; /* exception */
+
+       cl = (java_objectheader *) asm_calljavafunction(m, NULL, NULL, NULL, NULL);
+       if (!cl)
+               return false; /* exception */
+
+       LOADER_INC();
+       success = load_class_from_classloader(name,cl,result);
+       LOADER_DEC();
+       return success;
+}
 
 /* load_class_from_classloader *************************************************
 
@@ -1866,17 +1928,24 @@ static bool load_attributes(classbuffer *cb, u4 num)
 bool load_class_from_classloader(utf *name,java_objectheader *cl,classinfo **result)
 {
        classinfo *r;
+       bool success;
 
        LOADER_ASSERT(name);
        LOADER_ASSERT(result);
 
 #ifdef LOADER_VERBOSE
+       LOADER_INDENT();
        fprintf(stderr,"load_class_from_classloader(");
        utf_fprint(stderr,name);fprintf(stderr,",%p)\n",(void*)cl);
 #endif
 
        /* lookup if this class has already been loaded */
        *result = classcache_lookup(cl,name);
+#ifdef LOADER_VERBOSE
+       if (*result)
+               fprintf(stderr,"        cached -> %p\n",(void*)(*result));
+#endif
+
        if (*result)
                return true;
 
@@ -1885,6 +1954,37 @@ bool load_class_from_classloader(utf *name,java_objectheader *cl,classinfo **res
        if (cl) {
                methodinfo *lc;
 
+               /* handle array classes */
+               if (name->text[0] == '[') {
+                       char *utf_ptr = name->text + 1;
+                       int len = name->blength - 1;
+                       classinfo *comp;
+                       switch (*utf_ptr) {
+                               case 'L':
+                                       utf_ptr++;
+                                       len -= 2;
+                                       /* FALLTHROUGH */
+                               case '[':
+                                       /* load the component class */
+                                       LOADER_INC();
+                                       if (!load_class_from_classloader(utf_new(utf_ptr,len),cl,&comp)) {
+                                               LOADER_DEC();
+                                               return false;
+                                       }
+                                       LOADER_DEC();
+                                       /* create the array class */
+                                       *result = class_array_of(comp,false);
+                                       return (*result != 0);
+                                       break;
+                               default:
+                                       /* primitive array classes are loaded by the bootstrap loader */
+                                       LOADER_INC();
+                                       success = load_class_bootstrap(name,result);
+                                       LOADER_DEC();
+                                       return success;
+                       }
+               }
+               
                LOADER_ASSERT(class_java_lang_Object);
 
                lc = class_resolveclassmethod(cl->vftbl->class,
@@ -1896,15 +1996,17 @@ bool load_class_from_classloader(utf *name,java_objectheader *cl,classinfo **res
                if (!lc)
                        return false; /* exception */
 
+               LOADER_INC();
                r = (classinfo *) asm_calljavafunction(lc,
                                                                                           cl,
                                                                                           javastring_new(name),
                                                                                           NULL, NULL);
+               LOADER_DEC();
 
                /* store this class in the loaded class cache */
                if (r && !classcache_store(cl,r)) {
                        r->loaded = false;
-                       class_remove(r);
+                       class_free(r);
                        r = NULL; /* exception */
                }
 
@@ -1912,7 +2014,10 @@ bool load_class_from_classloader(utf *name,java_objectheader *cl,classinfo **res
                return (r != NULL);
        } 
 
-       return load_class_bootstrap(name,result);
+       LOADER_INC();
+       success = load_class_bootstrap(name,result);
+       LOADER_DEC();
+       return success;
 }
 
 
@@ -1946,26 +2051,26 @@ bool load_class_bootstrap(utf *name,classinfo **result)
        if (*result)
                return true;
 
+       /* check if this class has already been defined */
+       *result = classcache_lookup_defined(NULL,name);
+       if (*result)
+               return true;
+
 #ifdef LOADER_VERBOSE
+       LOADER_INDENT();
        fprintf(stderr,"load_class_bootstrap(");
        utf_fprint(stderr,name);fprintf(stderr,")\n");
 #endif
 
        /* create the classinfo */
-       c = class_new(name);
-
-       if (name == utf_java_lang_Object)
-               class_java_lang_Object = c;
-
-       /* store this class in the loaded class cache */
-       /* XXX we temporarily need this to avoid loading a bootstrap class multiple times */
-       if (!classcache_store(NULL,c)) {
-               c->loaded = false;
-               class_remove(c);
-               return false;
-       }
-
-       if (c->loaded) {
+       c = create_classinfo(name);
+       
+       /* handle array classes */
+       if (name->text[0] == '[') {
+               LOADER_INC();
+               load_newly_created_array(c,NULL);
+               LOADER_DEC();
+               LOADER_ASSERT(c->loaded);
                *result = c;
                return true;
        }
@@ -2006,15 +2111,9 @@ bool load_class_bootstrap(utf *name,classinfo **result)
        
        /* load the class from the buffer */
 
+       LOADER_INC();
        r = load_class_from_classbuffer(cb);
-
-       /* if return value is NULL, we had a problem and the class is not loaded */
-       if (!r) {
-               c->loaded = false;
-
-               /* now free the allocated memory, otherwise we could ran into a DOS */
-               class_remove(c);
-       }
+       LOADER_DEC();
 
        /* free memory */
        suck_stop(cb);
@@ -2028,18 +2127,25 @@ bool load_class_bootstrap(utf *name,classinfo **result)
                compilingtime_start();
 #endif
 
-#if XXX
+       if (!r) {
+#if defined(USE_THREADS)
+               builtin_monitorexit((java_objectheader *) c);
+#endif
+               class_free(c);
+       }
+
        /* store this class in the loaded class cache */
        if (r && !classcache_store(NULL,c)) {
-               c->loaded = false;
-               class_remove(c);
+#if defined(USE_THREADS)
+               builtin_monitorexit((java_objectheader *) c);
+#endif
+               class_free(c);
                r = NULL; /* exception */
        }
-#endif
 
 #if defined(USE_THREADS)
        /* leave the monitor */
-       builtin_monitorexit((java_objectheader *) c);
+       if (c) builtin_monitorexit((java_objectheader *) c);
 #endif
 
        *result = r;
@@ -2082,6 +2188,13 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
        if (c->loaded)
                return c;
 
+#ifdef LOADER_VERBOSE
+       LOADER_INDENT();
+       fprintf(stderr,"load_class_from_classbuffer(");
+       utf_fprint(stderr,c->name);fprintf(stderr,")\n");
+       LOADER_INC();
+#endif
+
 #if defined(STATISTICS)
        if (opt_stat)
                count_class_loads++;
@@ -2494,6 +2607,7 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
        if (loadverbose)
                log_message_class("Loading done class: ", c);
 
+       LOADER_DEC();
        return c;
 
 return_exception:
@@ -2501,59 +2615,89 @@ return_exception:
        dump_release(dumpsize);
 
        /* an exception has been thrown */
+       LOADER_DEC();
        return NULL;
 }
 
 
 
-/******************* Function: class_new_array *********************************
+/***************** Function: load_newly_created_array**** **********************
+
+    Load a newly created array class.
+
+       Note:
+               This is an internal function. Do not use it unless you know exactly
+               what you are doing!
 
-    This function is called by class_new to setup an array class.
+               Use one of the load_class_... functions for general array class loading.
 
 *******************************************************************************/
 
-void class_new_array(classinfo *c)
+bool load_newly_created_array(classinfo *c,java_objectheader *loader)
 {
        classinfo *comp = NULL;
        methodinfo *clone;
        methoddesc *clonedesc;
        constant_classref *classrefs;
        int namelen;
+       java_objectheader *definingloader = NULL;
+
+#ifdef LOADER_VERBOSE
+       LOADER_INDENT();
+       fprintf(stderr,"load_newly_created_array(");utf_fprint_classname(stderr,c->name);
+       fprintf(stderr,") loader=%p\n",loader);
+#endif
 
        /* Check array class name */
        namelen = c->name->blength;
-       if (namelen < 2 || c->name->text[0] != '[')
-               panic("Invalid array class name");
+       if (namelen < 2 || c->name->text[0] != '[') {
+               *exceptionptr = new_internalerror("Invalid array class name");
+               return false;
+       }
 
        /* Check the component type */
        switch (c->name->text[1]) {
        case '[':
                /* c is an array of arrays. We have to create the component class. */
-               if (opt_eager) {
-                       comp = class_new_intern(utf_new_intern(c->name->text + 1,
-                                                                                                  namelen - 1));
-                       LOADER_ASSERT(comp->loaded);
-                       list_addfirst(&unlinkedclasses, comp);
-
-               } else {
-                       comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
+               LOADER_INC();
+               if (!load_class_from_classloader(utf_new_intern(c->name->text + 1,
+                                                                                                               namelen - 1),
+                                                                                loader,
+                                                                                &comp)) 
+               {
+                       LOADER_DEC();
+                       return false;
                }
+               LOADER_DEC();
+               LOADER_ASSERT(comp->loaded);
+               if (opt_eager)
+                       if (!link_class(c))
+                               return false;
+               definingloader = comp->classloader;
                break;
 
        case 'L':
                /* c is an array of objects. */
-               if (namelen < 4 || c->name->text[namelen - 1] != ';')
-                       panic("Invalid array class name");
-
-               if (opt_eager) {
-                       comp = class_new_intern(utf_new_intern(c->name->text + 2,
-                                                                                                  namelen - 3));
-                       LOADER_ASSERT(comp->loaded);
-                       list_addfirst(&unlinkedclasses, comp);
+               if (namelen < 4 || c->name->text[namelen - 1] != ';') {
+                       *exceptionptr = new_internalerror("Invalid array class name");
+                       return false;
+               }
 
-               } else {
-                       comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
+               LOADER_INC();
+               if (!load_class_from_classloader(utf_new_intern(c->name->text + 2,
+                                                                                                               namelen - 3),
+                                                                                loader,
+                                                                                &comp)) 
+               {
+                       LOADER_DEC();
+                       return false;
                }
+               LOADER_DEC();
+               LOADER_ASSERT(comp->loaded);
+               if (opt_eager)
+                       if (!link_class(c))
+                               return false;
+               definingloader = comp->classloader;
                break;
        }
 
@@ -2617,8 +2761,13 @@ void class_new_array(classinfo *c)
        c->parseddescsize = sizeof(methodinfo);
        c->classrefs = classrefs;
        c->classrefcount = 1;
+       c->classloader = definingloader;
 
-       /* XXX insert class into the loaded class cache */
+       /* insert class into the loaded class cache */
+       if (!classcache_store(loader,c))
+               return false;
+
+       return true;
 }
 
 
@@ -3445,17 +3594,6 @@ void class_showmethods (classinfo *c)
 
 void loader_close()
 {
-       classinfo *c;
-       s4 slot;
-
-       for (slot = 0; slot < class_hash.size; slot++) {
-               c = class_hash.ptr[slot];
-
-               while (c) {
-                       class_free(c);
-                       c = c->hashlink;
-               }
-       }
 }
 
 
index cbcc8d8ec7dbf543057d28cbf092540041a5b8fd..5df0c3561bc68fc38560ae96f7df1f902c7ab08d 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: Reinhard Grafl
 
-   $Id: loader.h 2193 2005-04-02 19:33:43Z edwin $
+   $Id: loader.h 2195 2005-04-03 16:53:16Z edwin $
 */
 
 
@@ -168,9 +168,12 @@ inline u4 suck_u4(classbuffer *cb);
 void loader_close(void);
 
 /* class loading functions */
+bool load_class_from_sysloader(utf *name, classinfo **result);
 bool load_class_from_classloader(utf *name, java_objectheader *cl, classinfo **result);
 bool load_class_bootstrap(utf *name,classinfo **result);
+/* (don't use the following directly:) */
 classinfo *load_class_from_classbuffer(classbuffer *cb);
+bool load_newly_created_array(classinfo *c,java_objectheader *loader);
 
 
 /* retrieve constantpool element */
@@ -206,8 +209,6 @@ void class_showconstantpool(classinfo *c);
 /* return the primitive class inidicated by the given signature character */
 classinfo *class_primitive_from_sig(char sig);
 
-/* (used by class_new, don't use directly) */
-void class_new_array(classinfo *c);
 
 /* debug helpers */
 void fprintflags(FILE *fp, u2 f);
index f5f2b8b6205d6d132990bf8d33b9212735894b82..0f30a3d825eff7685356ee5feb75f93ef3d76f90 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: resolve.c 2194 2005-04-03 16:13:27Z twisti $
+   $Id: resolve.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -124,7 +124,9 @@ resolve_class(classinfo *referer,methodinfo *refmethod,
                                                return true; /* be lazy */
                                        }
                                        /* create the array class */
-                                       cls = class_array_of(cls);
+                                       cls = class_array_of(cls,false);
+                                       if (!cls)
+                                               return false; /* exception */
                        }
                }
                else {
@@ -190,6 +192,12 @@ resolve_classref_or_classinfo(methodinfo *refmethod,
        RESOLVE_ASSERT(mode == resolveEager || mode == resolveLazy);
        RESOLVE_ASSERT(result);
 
+#ifdef RESOLVE_VERBOSE
+       fprintf(stderr,"resolve_classref_or_classinfo(");
+       utf_fprint(stderr,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
+       fprintf(stderr,",%i,%i)\n",mode,link);
+#endif
+
        *result = NULL;
 
        if (IS_CLASSREF(cls)) {
@@ -716,7 +724,7 @@ unresolved_subtype_set_from_typeinfo(classinfo *referer,methodinfo *refmethod,
 #ifdef RESOLVE_VERBOSE
        fprintf(stderr,"unresolved_subtype_set_from_typeinfo\n");
 #ifdef TYPEINFO_DEBUG
-       typeinfo_print(stderr,tinfo,4);
+       /*typeinfo_print(stderr,tinfo,4);*/
        fprintf(stderr,"\n");
 #endif
        fprintf(stderr,"    declared type:");utf_fprint(stderr,declaredtype->name);
@@ -846,7 +854,7 @@ create_unresolved_field(classinfo *referer,methodinfo *refmethod,
        fprintf(stderr,"    desc   : ");utf_fprint(stderr,fieldref->descriptor);fputc('\n',stderr);
        fprintf(stderr,"    type   : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
        fputc('\n',stderr);
-       fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);
+       /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
 #endif
 
        ref->fieldref = fieldref;
@@ -927,7 +935,7 @@ create_unresolved_method(classinfo *referer,methodinfo *refmethod,
        fprintf(stderr,"    class  : ");utf_fprint(stderr,methodref->classref->name);fputc('\n',stderr);
        fprintf(stderr,"    name   : ");utf_fprint(stderr,methodref->name);fputc('\n',stderr);
        fprintf(stderr,"    desc   : ");utf_fprint(stderr,methodref->descriptor);fputc('\n',stderr);
-       fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);
+       /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
 #endif
 
        ref = NEW(unresolved_method);
index a9da845999101780988b9bc632f0685a9a3c00d7..aa98ddffc73899d3169556eb9557e73601f4aa83 100644 (file)
@@ -35,7 +35,7 @@
        - the heap
        - additional support functions
 
-   $Id: tables.c 2098 2005-03-27 19:00:02Z edwin $
+   $Id: tables.c 2195 2005-04-03 16:53:16Z edwin $
 
 */
 
@@ -106,7 +106,6 @@ void tables_init()
 {
        init_hashtable(&utf_hash,    UTF_HASHSTART);  /* hashtable for utf8-symbols */
        init_hashtable(&string_hash, HASHSTART);      /* hashtable for javastrings */
-       init_hashtable(&class_hash,  HASHSTART);      /* hashtable for classes */ 
 
        classcache_init();
 
@@ -161,7 +160,6 @@ void tables_close()
        /* dispose hashtable structures */
        MFREE(utf_hash.ptr,    void*, utf_hash.size);
        MFREE(string_hash.ptr, void*, string_hash.size);
-       MFREE(class_hash.ptr,  void*, class_hash.size);
 }