* src/vm/jit/i386/codegen.cn (codegen): Use the new functions for
[cacao.git] / src / vm / class.c
index 044fe313e2899b85d633de21072dc835078c9985..50b6fd24fa48fa450de1c7f49fc705b732a53e83 100644 (file)
@@ -31,7 +31,7 @@
             Christian Thalinger
                        Edwin Steiner
 
-   $Id: class.c 4752 2006-04-12 08:34:59Z edwin $
+   $Id: class.c 6033 2006-11-21 16:56:56Z michi $
 
 */
 
 
 #include "mm/memory.h"
 
-#if defined(USE_THREADS)
-# if defined(NATIVE_THREADS)
-#  include "threads/native/threads.h"
-# else
-#  include "threads/green/threads.h"
-#  include "threads/green/locks.h"
-# endif
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
 #endif
 
 #include "toolbox/logging.h"
 #include "vm/utf8.h"
 
 
-/******************************************************************************/
-/* DEBUG HELPERS                                                              */
-/******************************************************************************/
-
-#ifndef NDEBUG
-#define CLASS_DEBUG
-#endif
-
-#ifdef CLASS_DEBUG
-#define CLASS_ASSERT(cond)  assert(cond)
-#else
-#define CLASS_ASSERT(cond)
-#endif
-
-
 /* global variables ***********************************************************/
 
 list unlinkedclasses;                   /* this is only used for eager class  */
@@ -102,6 +82,7 @@ classinfo *class_java_lang_String;
 classinfo *class_java_lang_System;
 classinfo *class_java_lang_Thread;
 classinfo *class_java_lang_ThreadGroup;
+classinfo *class_java_lang_VMSystem;
 classinfo *class_java_lang_VMThread;
 classinfo *class_java_io_Serializable;
 
@@ -111,12 +92,14 @@ classinfo *class_java_io_Serializable;
 classinfo *class_java_lang_Throwable;
 classinfo *class_java_lang_VMThrowable;
 classinfo *class_java_lang_Error;
-classinfo *class_java_lang_NoClassDefFoundError;
+classinfo *class_java_lang_AbstractMethodError;
 classinfo *class_java_lang_LinkageError;
+classinfo *class_java_lang_NoClassDefFoundError;
 classinfo *class_java_lang_NoSuchMethodError;
 classinfo *class_java_lang_OutOfMemoryError;
 
 classinfo *class_java_lang_Exception;
+classinfo *class_java_lang_ClassCastException;
 classinfo *class_java_lang_ClassNotFoundException;
 classinfo *class_java_lang_IllegalArgumentException;
 classinfo *class_java_lang_IllegalMonitorStateException;
@@ -208,7 +191,7 @@ classinfo *class_create_classinfo(utf *classname)
 
 #if defined(ENABLE_STATISTICS)
        if (opt_stat)
-               count_class_infos += sizeof(classinfo);
+               size_classinfo += sizeof(classinfo);
 #endif
 
        /* we use a safe name for temporarily unnamed classes */
@@ -236,8 +219,8 @@ classinfo *class_create_classinfo(utf *classname)
        if (classname != utf_not_named_yet)
                class_set_packagename(c);
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       initObjectLock(&c->object.header);
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(&c->object.header);
 #endif
 
        return c;
@@ -401,7 +384,9 @@ void class_free(classinfo *c)
        if (c->fields) {
                for (i = 0; i < c->fieldscount; i++)
                        field_free(&(c->fields[i]));
-/*     MFREE(c->fields, fieldinfo, c->fieldscount); */
+#if defined(ENABLE_CACAO_GC)
+               MFREE(c->fields, fieldinfo, c->fieldscount);
+#endif
        }
        
        if (c->methods) {
@@ -464,15 +449,15 @@ static classinfo *get_array_class(utf *name,java_objectheader *initloader,
                        return NULL;
        }
 
-       CLASS_ASSERT(c);
-       CLASS_ASSERT(c->state & CLASS_LOADED);
-       CLASS_ASSERT(c->classloader == defloader);
+       assert(c);
+       assert(c->state & CLASS_LOADED);
+       assert(c->classloader == defloader);
 
        if (link && !(c->state & CLASS_LINKED))
                if (!link_class(c))
                        return NULL;
 
-       CLASS_ASSERT(!link || (c->state & CLASS_LINKED));
+       assert(!link || (c->state & CLASS_LINKED));
 
        return c;
 }
@@ -489,6 +474,10 @@ classinfo *class_array_of(classinfo *component, bool link)
 {
     s4 namelen;
     char *namebuf;
+       s4 dumpsize;
+       classinfo *c;
+
+       dumpsize = dump_size();
 
     /* Assemble the array class name */
     namelen = component->name->blength;
@@ -510,10 +499,14 @@ classinfo *class_array_of(classinfo *component, bool link)
         namelen += 3;
     }
 
-       return get_array_class(utf_new(namebuf, namelen),
-                                                  component->classloader,
-                                                  component->classloader,
-                                                  link);
+       c = get_array_class(utf_new(namebuf, namelen),
+                                               component->classloader,
+                                               component->classloader,
+                                               link);
+
+       dump_release(dumpsize);
+
+       return c;
 }
 
 
@@ -528,6 +521,10 @@ classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
 {
     s4 namelen;
     char *namebuf;
+       s4 dumpsize;
+       classinfo *c;
+
+       dumpsize = dump_size();
 
        if (dim < 1) {
                log_text("Invalid array dimension requested");
@@ -553,10 +550,14 @@ classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
     }
        memset(namebuf, '[', dim);
 
-       return get_array_class(utf_new(namebuf, namelen),
-                                                  element->classloader,
-                                                  element->classloader,
-                                                  link);
+       c = get_array_class(utf_new(namebuf, namelen),
+                                               element->classloader,
+                                               element->classloader,
+                                               link);
+
+       dump_release(dumpsize);
+
+       return c;
 }
 
 
@@ -581,9 +582,9 @@ constant_classref *class_lookup_classref(classinfo *cls, utf *name)
        extra_classref *xref;
        int count;
 
-       CLASS_ASSERT(cls);
-       CLASS_ASSERT(name);
-       CLASS_ASSERT(!cls->classrefcount || cls->classrefs);
+       assert(cls);
+       assert(name);
+       assert(!cls->classrefcount || cls->classrefs);
        
        /* first search the main classref table */
        count = cls->classrefcount;
@@ -624,8 +625,8 @@ constant_classref *class_get_classref(classinfo *cls, utf *name)
        constant_classref *ref;
        extra_classref *xref;
 
-       CLASS_ASSERT(cls);
-       CLASS_ASSERT(name);
+       assert(cls);
+       assert(name);
 
        ref = class_lookup_classref(cls,name);
        if (ref)
@@ -682,9 +683,13 @@ constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *r
 {
     s4 namelen;
     char *namebuf;
+       s4 dumpsize;
+       constant_classref *cr;
+
+       assert(ref);
+       assert(dim >= 1 && dim <= 255);
 
-       CLASS_ASSERT(ref);
-       CLASS_ASSERT(dim >= 1 && dim <= 255);
+       dumpsize = dump_size();
 
     /* Assemble the array class name */
     namelen = ref->name->blength;
@@ -705,7 +710,11 @@ constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *r
     }
        memset(namebuf, '[', dim);
 
-    return class_get_classref(ref->referer,utf_new(namebuf, namelen));
+    cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
+
+       dump_release(dumpsize);
+
+       return cr;
 }
 
 
@@ -730,7 +739,7 @@ constant_classref *class_get_classref_component_of(constant_classref *ref)
        s4 namelen;
        char *name;
        
-       CLASS_ASSERT(ref);
+       assert(ref);
 
        name = ref->name->text;
        if (*name++ != '[')
@@ -818,22 +827,26 @@ static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
 {
        methodinfo *m;
        s4          i;
-       
+
+       /* try to find the method in the class */
+
        m = class_findmethod(c, name, desc);
 
-       if (m)
+       if (m != NULL)
                return m;
 
-       /* try the superinterfaces */
+       /* no method found? try the superinterfaces */
 
        for (i = 0; i < c->interfacescount; i++) {
                m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
-                                                                                               name, desc);
+                                                                                                       name, desc);
 
-               if (m)
+               if (m != NULL)
                        return m;
        }
-       
+
+       /* no method found */
+
        return NULL;
 }
 
@@ -855,9 +868,6 @@ methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
        methodinfo *m;
        s4          i;
 
-       /* XXX resolve class c */
-       /* XXX check access from REFERER to C */
-       
 /*     if (c->flags & ACC_INTERFACE) { */
 /*             if (throwexception) */
 /*                     *exceptionptr = */
@@ -871,28 +881,28 @@ methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
 
        m = class_resolvemethod(cls, name, desc);
 
-       if (m)
+       if (m != NULL)
                goto found;
 
        /* try the superinterfaces */
 
        for (i = 0; i < c->interfacescount; i++) {
                m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
-                                                                                                name, desc);
+                                                                                               name, desc);
 
-               if (m)
+               if (m != NULL)
                        goto found;
        }
        
        if (throwexception)
-               *exceptionptr = exceptions_new_nosuchmethoderror(c, name, desc);
+               exceptions_throw_nosuchmethoderror(c, name, desc);
 
        return NULL;
 
  found:
        if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
                if (throwexception)
-                       *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
+                       exceptions_throw_abstractmethoderror();
 
                return NULL;
        }
@@ -918,9 +928,6 @@ methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
 {
        methodinfo *mi;
 
-       /* XXX resolve class c */
-       /* XXX check access from REFERER to C */
-       
        if (!(c->flags & ACC_INTERFACE)) {
                if (throwexception)
                        *exceptionptr =
@@ -1071,9 +1078,6 @@ fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
 {
        fieldinfo *fi;
 
-       /* XXX resolve class c */
-       /* XXX check access from REFERER to C */
-       
        fi = class_resolvefield_int(c, name, desc);
 
        if (!fi) {
@@ -1154,7 +1158,7 @@ void class_print(classinfo *c)
                return;
        }
 
-       utf_display(c->name);
+       utf_display_printable_ascii(c->name);
        class_printflags(c);
 }
 #endif
@@ -1174,7 +1178,7 @@ void class_classref_print(constant_classref *cr)
                return;
        }
 
-       utf_display(cr->name);
+       utf_display_printable_ascii(cr->name);
        printf("(ref.by ");
        if (cr->referer)
                class_print(cr->referer);
@@ -1215,6 +1219,40 @@ void class_classref_println(constant_classref *cr)
 #endif
 
 
+/* class_classref_or_classinfo_print *******************************************
+
+   Prints classname plus referer class.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_or_classinfo_print(classref_or_classinfo c)
+{
+       if (c.any == NULL) {
+               printf("(classref_or_classinfo) NULL");
+               return;
+       }
+       if (IS_CLASSREF(c))
+               class_classref_print(c.ref);
+       else
+               class_print(c.cls);
+}
+#endif
+
+
+/* class_classref_or_classinfo_println *****************************************
+
+   Prints classname plus referer class and a newline.
+
+*******************************************************************************/
+
+void class_classref_or_classinfo_println(classref_or_classinfo c)
+{
+       class_classref_or_classinfo_println(c);
+       printf("\n");
+}
+
+
 /* class_showconstantpool ******************************************************
 
    Dump the constant pool of the given class to stdout.
@@ -1238,29 +1276,23 @@ void class_showconstantpool (classinfo *c)
                        switch (c -> cptags [i]) {
                        case CONSTANT_Class:
                                printf ("Classreference -> ");
-                               utf_display ( ((constant_classref*)e) -> name );
+                               utf_display_printable_ascii ( ((constant_classref*)e) -> name );
                                break;
-                               
                        case CONSTANT_Fieldref:
-                               printf ("Fieldref -> "); goto displayFMI;
+                               printf ("Fieldref -> ");
+                               field_fieldref_print((constant_FMIref *) e);
+                               break;
                        case CONSTANT_Methodref:
-                               printf ("Methodref -> "); goto displayFMI;
+                               printf ("Methodref -> ");
+                               method_methodref_print((constant_FMIref *) e);
+                               break;
                        case CONSTANT_InterfaceMethodref:
-                               printf ("InterfaceMethod -> "); goto displayFMI;
-                       displayFMI:
-                               {
-                                       constant_FMIref *fmi = e;
-                                       utf_display ( fmi->classref->name );
-                                       printf (".");
-                                       utf_display ( fmi->name);
-                                       printf (" ");
-                                       utf_display ( fmi->descriptor );
-                               }
+                               printf ("InterfaceMethod -> ");
+                               method_methodref_print((constant_FMIref *) e);
                                break;
-
                        case CONSTANT_String:
                                printf ("String -> ");
-                               utf_display (e);
+                               utf_display_printable_ascii (e);
                                break;
                        case CONSTANT_Integer:
                                printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
@@ -1286,14 +1318,14 @@ void class_showconstantpool (classinfo *c)
                                {
                                        constant_nameandtype *cnt = e;
                                        printf ("NameAndType: ");
-                                       utf_display (cnt->name);
+                                       utf_display_printable_ascii (cnt->name);
                                        printf (" ");
-                                       utf_display (cnt->descriptor);
+                                       utf_display_printable_ascii (cnt->descriptor);
                                }
                                break;
                        case CONSTANT_Utf8:
                                printf ("Utf8 -> ");
-                               utf_display (e);
+                               utf_display_printable_ascii (e);
                                break;
                        default: 
                                log_text("Invalid type of ConstantPool-Entry");
@@ -1324,12 +1356,12 @@ void class_showmethods (classinfo *c)
        printf("\n");
 
        printf("This: ");
-       utf_display(c->name);
+       utf_display_printable_ascii(c->name);
        printf("\n");
 
        if (c->super.cls) {
                printf("Super: ");
-               utf_display(c->super.cls->name);
+               utf_display_printable_ascii(c->super.cls->name);
                printf ("\n");
        }
 
@@ -1338,7 +1370,7 @@ void class_showmethods (classinfo *c)
        printf("Interfaces:\n");        
        for (i = 0; i < c->interfacescount; i++) {
                printf("   ");
-               utf_display(c->interfaces[i].cls->name);
+               utf_display_printable_ascii(c->interfaces[i].cls->name);
                printf (" (%d)\n", c->interfaces[i].cls->index);
        }