Merged revisions 7797-7917 via svnmerge from
[cacao.git] / src / vmcore / class.c
index 15e97e20f435f70ad670da4b572b5f856119cba3..cbd0a509bde86878951367cb90ac28ed0d339244 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: class.c 7257 2007-01-29 23:07:40Z twisti $
+   $Id: class.c 7918 2007-05-20 20:42:18Z michi $
 
 */
 
 
 #include "vm/types.h"
 
+#include "arch.h"
+
 #include "mm/memory.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
+#include "threads/lock-common.h"
 
 #include "toolbox/logging.h"
 
 #include "vm/exceptions.h"
 #include "vm/global.h"
 
+#include "vm/jit/asmpart.h"
+
 #include "vmcore/class.h"
 #include "vmcore/classcache.h"
 #include "vmcore/loader.h"
 #include "vmcore/options.h"
-#include "vmcore/resolve.h"
 
 #if defined(ENABLE_STATISTICS)
 # include "vmcore/statistics.h"
@@ -63,7 +64,7 @@
 
 /* global variables ***********************************************************/
 
-list unlinkedclasses;                   /* this is only used for eager class  */
+list_t unlinkedclasses;                 /* this is only used for eager class  */
                                         /* loading                            */
 
 
@@ -197,7 +198,8 @@ classinfo *class_create_classinfo(utf *classname)
 #endif
 
        /* we use a safe name for temporarily unnamed classes */
-       if (!classname)
+
+       if (classname == NULL)
                classname = utf_not_named_yet;
 
 #if !defined(NDEBUG)
@@ -207,23 +209,39 @@ classinfo *class_create_classinfo(utf *classname)
 
        /* GCNEW_UNCOLLECTABLE clears the allocated memory */
 
+#if defined(ENABLE_GC_CACAO)
+       c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
+#else
        c = GCNEW_UNCOLLECTABLE(classinfo, 1);
        /*c=NEW(classinfo);*/
+#endif
        c->name = classname;
 
        /* Set the header.vftbl of all loaded classes to the one of
        java.lang.Class, so Java code can use a class as object. */
 
-       if (class_java_lang_Class)
-               if (class_java_lang_Class->vftbl)
+       if (class_java_lang_Class != NULL)
+               if (class_java_lang_Class->vftbl != NULL)
                        c->object.header.vftbl = class_java_lang_Class->vftbl;
-       
+
+#if defined(ENABLE_JAVASE)
+       /* check if the class is a reference class and flag it */
+
+       if (classname == utf_java_lang_ref_SoftReference) {
+               c->flags |= ACC_CLASS_SOFT_REFERENCE;
+       }
+       else if (classname == utf_java_lang_ref_WeakReference) {
+               c->flags |= ACC_CLASS_WEAK_REFERENCE;
+       }
+       else if (classname == utf_java_lang_ref_PhantomReference) {
+               c->flags |= ACC_CLASS_PHANTOM_REFERENCE;
+       }
+#endif
+
        if (classname != utf_not_named_yet)
                class_set_packagename(c);
 
-#if defined(ENABLE_THREADS)
-       lock_init_object_lock(&c->object.header);
-#endif
+       LOCK_INIT_OBJECT_LOCK(&c->object.header);
 
        return c;
 }
@@ -496,12 +514,16 @@ bool class_load_attributes(classbuffer *cb)
                        if (!loader_load_attribute_signature(cb, &(c->signature)))
                                return false;
                }
+#if 0
+               /* XXX We can't do a release with that enabled */
+
                else if (attribute_name == utf_RuntimeVisibleAnnotations) {
                        /* RuntimeVisibleAnnotations */
 
                        if (!annotation_load_attribute_runtimevisibleannotations(cb))
                                return false;
                }
+#endif
 #endif
                else {
                        /* unknown attribute */
@@ -686,8 +708,8 @@ void class_free(classinfo *c)
 
 *******************************************************************************/
 
-static classinfo *get_array_class(utf *name,java_objectheader *initloader,
-                                                                                       java_objectheader *defloader,bool link)
+static classinfo *get_array_class(utf *name,classloader *initloader,
+                                                                                       classloader *defloader,bool link)
 {
        classinfo *c;
        
@@ -1366,6 +1388,56 @@ bool class_issubclass(classinfo *sub, classinfo *super)
 }
 
 
+/* class_isanysubclass *********************************************************
+
+   Checks a subclass relation between two classes. Implemented
+   interfaces are interpreted as super classes.
+
+   Return value: 1 ... sub is subclass of super
+                 0 ... otherwise
+
+*******************************************************************************/
+
+bool class_isanysubclass(classinfo *sub, classinfo *super)
+{
+       castinfo classvalues;
+       u4       diffval;
+       bool     result;
+
+       /* This is the trivial case. */
+
+       if (sub == super)
+               return true;
+
+       /* Primitive classes are only subclasses of themselves. */
+
+       if ((sub->flags & ACC_CLASS_PRIMITIVE) ||
+               (super->flags & ACC_CLASS_PRIMITIVE))
+               return false;
+
+       /* Check for interfaces. */
+
+       if (super->flags & ACC_INTERFACE) {
+               result = (sub->vftbl->interfacetablelength > super->index) &&
+                       (sub->vftbl->interfacetable[-super->index] != NULL);
+       }
+       else {
+               /* java.lang.Object is the only super class of any
+                  interface. */
+
+               if (sub->flags & ACC_INTERFACE)
+                       return (super == class_java_lang_Object);
+
+               ASM_GETCLASSVALUES_ATOMIC(super->vftbl, sub->vftbl, &classvalues);
+
+               diffval = classvalues.sub_baseval - classvalues.super_baseval;
+               result  = diffval <= (u4) classvalues.super_diffval;
+       }
+
+       return result;
+}
+
+
 /* class_printflags ************************************************************
 
    Prints flags of a class.