* src/vm/jit/stack.c (stack_analyse): Do not set argintreguse to
[cacao.git] / src / vm / loader.c
index 5c0fcb706ad4b69cb17743cbedf3a88513d22fd0..9bc5b0d9f8e8890f407ea92a0124d4284902f127 100644 (file)
@@ -1,9 +1,9 @@
 /* src/vm/loader.c - class loader functions
 
-   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
-   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
-   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
-   Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+   J. Wenninger, Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
+   Contact: cacao@cacaojvm.org
 
    Authors: Reinhard Grafl
 
             Edwin Steiner
             Christian Thalinger
 
-   $Id: loader.c 3903 2005-12-07 17:43:29Z twisti $
+   $Id: loader.c 5250 2006-08-18 12:24:10Z twisti $
 
 */
 
+
+#include "config.h"
+
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 
-#include "config.h"
 #include "vm/types.h"
+
 #include "mm/memory.h"
 #include "native/native.h"
 #include "native/include/java_lang_Throwable.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/exceptions.h"
 #include "vm/builtin.h"
+#include "vm/classcache.h"
+#include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/linker.h"
 #include "vm/loader.h"
 #include "vm/statistics.h"
 #include "vm/stringlocal.h"
 #include "vm/suck.h"
-#include "vm/classcache.h"
+#include "vm/vm.h"
 
-#if defined(USE_ZLIB)
-# include "vm/unzip.h"
+#if defined(ENABLE_ZLIB)
+# include "vm/zip.h"
 #endif
 
 #include "vm/jit/asmpart.h"
-#include "vm/jit/codegen.inc.h"
+#include "vm/jit/codegen-common.h"
+#include "vm/rt-timing.h"
+
+#if defined(ENABLE_JVMTI)
+#include "native/jvmti/cacaodbg.h"
+#endif
 
 /******************************************************************************/
 /* DEBUG HELPERS                                                              */
 #endif
 
 
-/********************************************************************
-   list of classpath entries (either filesystem directories or 
-   ZIP/JAR archives
-********************************************************************/
-
-classpath_info *classpath_entries = NULL;
-
-
 /* loader_init *****************************************************************
 
    Initializes all lists and loads all classes required for the system
@@ -104,17 +100,17 @@ classpath_info *classpath_entries = NULL;
 
 *******************************************************************************/
  
-bool loader_init(u1 *stackbottom)
+bool loader_init(void)
 {
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       classpath_info *cpi;
+#if defined(ENABLE_THREADS)
+       list_classpath_entry *lce;
 
        /* Initialize the monitor pointer for zip/jar file locking. */
 
-       for (cpi = classpath_entries; cpi != NULL; cpi = cpi->next) {
-               if (cpi->type == CLASSPATH_ARCHIVE)
-                       initObjectLock(&cpi->header);
-       }
+       for (lce = list_first(list_classpath_entries); lce != NULL;
+                lce = list_next(list_classpath_entries, lce))
+               if (lce->type == CLASSPATH_ARCHIVE)
+                       lock_init_object_lock((java_objectheader *) lce);
 #endif
 
        /* load some important classes */
@@ -191,6 +187,10 @@ bool loader_init(u1 *stackbottom)
                  load_class_bootstrap(utf_java_lang_ThreadGroup)))
                return false;
 
+       if (!(class_java_lang_VMSystem =
+                 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
+               return false;
+
        if (!(class_java_lang_VMThread =
                  load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
                return false;
@@ -225,11 +225,6 @@ bool loader_init(u1 *stackbottom)
                  load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
                return false;
 
-#if defined(USE_THREADS)
-       if (stackbottom != 0)
-               initLocks();
-#endif
-
        return true;
 }
 
@@ -242,70 +237,65 @@ bool loader_init(u1 *stackbottom)
 
 void loader_load_all_classes(void)
 {
-       classpath_info *cpi;
-       classinfo      *c;
+       list_classpath_entry    *lce;
+#if defined(ENABLE_ZLIB)
+       hashtable               *ht;
+       s4                       slot;
+       hashtable_zipfile_entry *htzfe;
+       utf                     *u;
+#endif
 
-       for (cpi = classpath_entries; cpi != 0; cpi = cpi->next) {
-#if defined(USE_ZLIB)
-               if (cpi->type == CLASSPATH_ARCHIVE) {
-                       cacao_entry_s *ce;
-                       unz_s *s;
+       for (lce = list_first(list_classpath_entries); lce != NULL;
+                lce = list_next(list_classpath_entries, lce)) {
+#if defined(ENABLE_ZLIB)
+               if (lce->type == CLASSPATH_ARCHIVE) {
+                       /* get the classes hashtable */
 
-                       s = (unz_s *) cpi->uf;
-                       ce = s->cacao_dir_list;
-                               
-                       while (ce) {
-                               /* skip all entries in META-INF and .properties, .png files */
+                       ht = lce->htclasses;
 
-                               if (strncmp(ce->name->text, "META-INF", strlen("META-INF")) &&
-                                       !strstr(ce->name->text, ".properties") &&
-                                       !strstr(ce->name->text, ".png"))
-                                       c = load_class_bootstrap(ce->name);
+                       for (slot = 0; slot < ht->size; slot++) {
+                               htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
 
-                               ce = ce->next;
-                       }
+                               for (; htzfe; htzfe = htzfe->hashlink) {
+                                       u = htzfe->filename;
 
-               } else {
-#endif
-#if defined(USE_ZLIB)
-               }
-#endif
-       }
-}
+                                       /* skip all entries in META-INF and .properties,
+                       .png files */
 
+                                       if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
+                                               strstr(u->text, ".properties") ||
+                                               strstr(u->text, ".png"))
+                                               continue;
 
-/******************************************************************************/
-/******************* Some support functions ***********************************/
-/******************************************************************************/
+                                       /* load class from bootstrap classloader */
 
-void fprintflags (FILE *fp, u2 f)
-{
-   if ( f & ACC_PUBLIC )       fprintf (fp," PUBLIC");
-   if ( f & ACC_PRIVATE )      fprintf (fp," PRIVATE");
-   if ( f & ACC_PROTECTED )    fprintf (fp," PROTECTED");
-   if ( f & ACC_STATIC )       fprintf (fp," STATIC");
-   if ( f & ACC_FINAL )        fprintf (fp," FINAL");
-   if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
-   if ( f & ACC_VOLATILE )     fprintf (fp," VOLATILE");
-   if ( f & ACC_TRANSIENT )    fprintf (fp," TRANSIENT");
-   if ( f & ACC_NATIVE )       fprintf (fp," NATIVE");
-   if ( f & ACC_INTERFACE )    fprintf (fp," INTERFACE");
-   if ( f & ACC_ABSTRACT )     fprintf (fp," ABSTRACT");
-}
+                                       if (!load_class_bootstrap(u)) {
+                                               fprintf(stderr, "Error loading: ");
+                                               utf_fprint_printable_ascii_classname(stderr, u);
+                                               fprintf(stderr, "\n");
 
+#if !defined(NDEBUG)
+                                               /* print out exception and cause */
 
-/********** internal function: printflags  (only for debugging) ***************/
+                                               exceptions_print_exception(*exceptionptr);
+#endif
+                                       }
+                               }
+                       }
 
-void printflags(u2 f)
-{
-       fprintflags(stdout,f);
+               } else {
+#endif
+#if defined(ENABLE_ZLIB)
+               }
+#endif
+       }
 }
 
 
-/********************** Function: skipattributebody ****************************
+/* skipattributebody ***********************************************************
 
-       skips an attribute after the 16 bit reference to attribute_name has already
-       been read
+   Skips an attribute after the 16 bit reference to attribute_name has
+   already been read.
        
 *******************************************************************************/
 
@@ -433,11 +423,11 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
        cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
 
        if (cpcount < 1) {
-               *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
+               exceptions_throw_classformaterror(c, "Illegal constant pool size");
                return false;
        }
        
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        if (opt_stat)
                count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
 #endif
@@ -546,7 +536,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
                case CONSTANT_Integer: {
                        constant_integer *ci = NEW(constant_integer);
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
                        if (opt_stat)
                                count_const_pool_len += sizeof(constant_integer);
 #endif
@@ -565,7 +555,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
                case CONSTANT_Float: {
                        constant_float *cf = NEW(constant_float);
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
                        if (opt_stat)
                                count_const_pool_len += sizeof(constant_float);
 #endif
@@ -584,7 +574,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
                case CONSTANT_Long: {
                        constant_long *cl = NEW(constant_long);
                                        
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
                        if (opt_stat)
                                count_const_pool_len += sizeof(constant_long);
 #endif
@@ -597,8 +587,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
                        cpinfos[idx] = cl;
                        idx += 2;
                        if (idx > cpcount) {
-                               *exceptionptr =
-                                       new_classformaterror(c, "Invalid constant pool entry");
+                               exceptions_throw_classformaterror(c, "Invalid constant pool entry");
                                return false;
                        }
                        break;
@@ -607,7 +596,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
                case CONSTANT_Double: {
                        constant_double *cd = NEW(constant_double);
                                
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
                        if (opt_stat)
                                count_const_pool_len += sizeof(constant_double);
 #endif
@@ -620,8 +609,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
                        cpinfos[idx] = cd;
                        idx += 2;
                        if (idx > cpcount) {
-                               *exceptionptr =
-                                       new_classformaterror(c, "Invalid constant pool entry");
+                               exceptions_throw_classformaterror(c, "Invalid constant pool entry");
                                return false;
                        }
                        break;
@@ -645,7 +633,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
                        if (opt_verify &&
                                !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length))) 
                        {
-                               *exceptionptr = new_classformaterror(c,"Invalid UTF-8 string");
+                               exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
                                return false;
                        }
 #endif /* ENABLE_VERIFIER */
@@ -659,8 +647,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
                }
                                                                                
                default:
-                       *exceptionptr =
-                               new_classformaterror(c, "Illegal constant pool type");
+                       exceptions_throw_classformaterror(c, "Illegal constant pool type");
                        return false;
                }  /* end switch */
        } /* end while */
@@ -676,8 +663,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
 
 #ifdef ENABLE_VERIFIER
                if (opt_verify && !is_valid_name_utf(name)) {
-                       *exceptionptr = 
-                               new_classformaterror(c, "Class reference with invalid name");
+                       exceptions_throw_classformaterror(c, "Class reference with invalid name");
                        return false;
                }
 #endif /* ENABLE_VERIFIER */
@@ -697,7 +683,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
 
                        /* link the class later, because we cannot link the class currently
                           loading */
-                       list_addfirst(&unlinkedclasses, tc);
+                       list_add_first(&unlinkedclasses, tc);
                }
 
                /* the classref is created later */
@@ -724,7 +710,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
        while (forward_nameandtypes) {
                constant_nameandtype *cn = NEW(constant_nameandtype);   
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
                if (opt_stat)
                        count_const_pool_len += sizeof(constant_nameandtype);
 #endif
@@ -746,18 +732,16 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
                if (opt_verify) {
                        /* check name */
                        if (!is_valid_name_utf(cn->name)) {
-                               *exceptionptr =
-                                       new_classformaterror(c,
-                                                                                "Illegal Field name \"%s\"",
-                                                                                cn->name->text);
+                               exceptions_throw_classformaterror(c,
+                                                                                                 "Illegal Field name \"%s\"",
+                                                                                                 cn->name->text);
 
                                return false;
                        }
 
                        /* disallow referencing <clinit> among others */
                        if (cn->name->text[0] == '<' && cn->name != utf_init) {
-                               *exceptionptr =
-                                       new_classformaterror(c,"Illegal reference to special method");
+                               exceptions_throw_classformaterror(c, "Illegal reference to special method");
                                return false;
                        }
                }
@@ -774,7 +758,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
                constant_nameandtype *nat;
                constant_FMIref *fmi = NEW(constant_FMIref);
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
                if (opt_stat)
                        count_const_pool_len += sizeof(constant_FMIref);
 #endif
@@ -793,7 +777,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
 
                /* the classref is created later */
 
-               fmi->classref = (constant_classref *) (size_t) forward_fieldmethints->class_index;
+               fmi->p.index = forward_fieldmethints->class_index;
                fmi->name = nat->name;
                fmi->descriptor = nat->descriptor;
 
@@ -852,7 +836,7 @@ static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
        /* descriptor_pool_add accepts method descriptors, so we have to check  */
        /* against them here before the call of descriptor_to_basic_type below. */
        if (u->text[0] == '(') {
-               *exceptionptr = new_classformaterror(c,"Method descriptor used for field");
+               exceptions_throw_classformaterror(c, "Method descriptor used for field");
                return false;
        }
 
@@ -860,9 +844,9 @@ static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
        if (opt_verify) {
                /* check name */
                if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
-                       *exceptionptr = new_classformaterror(c,
-                                                                                                "Illegal Field name \"%s\"",
-                                                                                                f->name->text);
+                       exceptions_throw_classformaterror(c,
+                                                                                         "Illegal Field name \"%s\"",
+                                                                                         f->name->text);
                        return false;
                }
 
@@ -871,10 +855,9 @@ static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
 
                if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
                        ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
-                       *exceptionptr =
-                               new_classformaterror(c,
-                                                                        "Illegal field modifiers: 0x%X",
-                                                                        f->flags);
+                       exceptions_throw_classformaterror(c,
+                                                                                         "Illegal field modifiers: 0x%X",
+                                                                                         f->flags);
                        return false;
                }
 
@@ -882,32 +865,46 @@ static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
                        if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
                                != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
                                f->flags & ACC_TRANSIENT) {
-                               *exceptionptr =
-                                       new_classformaterror(c,
-                                                                                "Illegal field modifiers: 0x%X",
-                                                                                f->flags);
+                               exceptions_throw_classformaterror(c,
+                                                                                                 "Illegal field modifiers: 0x%X",
+                                                                                                 f->flags);
                                return false;
                        }
                }
        }
 #endif /* ENABLE_VERIFIER */
-               
-       f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
-       f->offset = 0;                           /* offset from start of object */
-       f->class = c;
-       f->xta = NULL;
-       
+
+       f->type   = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
+       f->offset = 0;                             /* offset from start of object */
+       f->class  = c;
+
        switch (f->type) {
-       case TYPE_INT:     f->value.i = 0; break;
-       case TYPE_FLOAT:   f->value.f = 0.0; break;
-       case TYPE_DOUBLE:  f->value.d = 0.0; break;
-       case TYPE_ADDRESS: f->value.a = NULL; break;
-       case TYPE_LONG:
+       case TYPE_INT:
+               f->value.i = 0;
+               break;
+
+       case TYPE_FLT:
+               f->value.f = 0.0;
+               break;
+
+       case TYPE_DBL:
+               f->value.d = 0.0;
+               break;
+
+       case TYPE_ADR:
+               f->value.a = NULL;
+               if (!(f->flags & ACC_STATIC))
+                       c->flags |= ACC_CLASS_HAS_POINTERS;
+               break;
+
+       case TYPE_LNG:
 #if U8_AVAILABLE
-               f->value.l = 0; break;
+               f->value.l = 0;
 #else
-               f->value.l.low = 0; f->value.l.high = 0; break;
+               f->value.l.low  = 0;
+               f->value.l.high = 0;
 #endif
+               break;
        }
 
        /* read attributes */
@@ -928,16 +925,13 @@ static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
 
                        /* check attribute length */
                        if (suck_u4(cb) != 2) {
-                               *exceptionptr =
-                                       new_classformaterror(c, "Wrong size for VALUE attribute");
+                               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
                                return false;
                        }
                        
                        /* constant value attribute */
                        if (pindex != field_load_NOVALUE) {
-                               *exceptionptr =
-                                       new_classformaterror(c,
-                                                                                "Multiple ConstantValue attributes");
+                               exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
                                return false;
                        }
                        
@@ -956,7 +950,7 @@ static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
                        }
                        break;
                                        
-                       case TYPE_LONG: {
+                       case TYPE_LNG: {
                                constant_long *cl; 
 
                                if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
@@ -966,7 +960,7 @@ static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
                        }
                        break;
 
-                       case TYPE_FLOAT: {
+                       case TYPE_FLT: {
                                constant_float *cf;
 
                                if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
@@ -976,7 +970,7 @@ static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
                        }
                        break;
                                                                                        
-                       case TYPE_DOUBLE: {
+                       case TYPE_DBL: {
                                constant_double *cd;
 
                                if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
@@ -986,7 +980,7 @@ static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
                        }
                        break;
                                                
-                       case TYPE_ADDRESS:
+                       case TYPE_ADR:
                                if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
                                        return false;
 
@@ -1031,20 +1025,18 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
 
        c = cb->class;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       initObjectLock(&m->header);
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(&m->header);
 #endif
 
-#ifdef STATISTICS
+#if defined(ENABLE_STATISTICS)
        if (opt_stat)
                count_all_methods++;
 #endif
 
-       m->thrownexceptionscount = 0;
-       m->linenumbercount = 0;
-       m->linenumbers = 0;
-       m->class = c;
-       m->nativelyoverloaded = false;
+       /* all fields of m have been zeroed in load_class_from_classbuffer */
+
+       m->class                 = c;
        
        if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
                return false;
@@ -1060,7 +1052,6 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
                return false;
 
        m->descriptor = u;
-       m->parseddesc = NULL;
 
        if (!descriptor_pool_add(descpool, u, &argcount))
                return false;
@@ -1068,13 +1059,13 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
 #ifdef ENABLE_VERIFIER
        if (opt_verify) {
                if (!is_valid_name_utf(m->name)) {
-                       *exceptionptr = new_classformaterror(c,"Method with invalid name");
+                       exceptions_throw_classformaterror(c, "Method with invalid name");
                        return false;
                }
 
                if (m->name->text[0] == '<' &&
                        m->name != utf_init && m->name != utf_clinit) {
-                       *exceptionptr = new_classformaterror(c,"Method with invalid special name");
+                       exceptions_throw_classformaterror(c, "Method with invalid special name");
                        return false;
                }
        }
@@ -1086,8 +1077,7 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
 #ifdef ENABLE_VERIFIER
        if (opt_verify) {
                if (argcount > 255) {
-                       *exceptionptr =
-                               new_classformaterror(c, "Too many arguments in signature");
+                       exceptions_throw_classformaterror(c, "Too many arguments in signature");
                        return false;
                }
 
@@ -1096,30 +1086,27 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
                        i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
 
                        if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
-                               *exceptionptr =
-                                       new_classformaterror(c,
-                                                                                "Illegal method modifiers: 0x%X",
-                                                                                m->flags);
+                               exceptions_throw_classformaterror(c,
+                                                                                                 "Illegal method modifiers: 0x%X",
+                                                                                                 m->flags);
                                return false;
                        }
 
                        if (m->flags & ACC_ABSTRACT) {
                                if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
                                                                 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
-                                       *exceptionptr =
-                                               new_classformaterror(c,
-                                                                                        "Illegal method modifiers: 0x%X",
-                                                                                        m->flags);
+                                       exceptions_throw_classformaterror(c,
+                                                                                                         "Illegal method modifiers: 0x%X",
+                                                                                                         m->flags);
                                        return false;
                                }
                        }
 
                        if (c->flags & ACC_INTERFACE) {
                                if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
-                                       *exceptionptr =
-                                               new_classformaterror(c,
-                                                                                        "Illegal method modifiers: 0x%X",
-                                                                                        m->flags);
+                                       exceptions_throw_classformaterror(c,
+                                                                                                         "Illegal method modifiers: 0x%X",
+                                                                                                         m->flags);
                                        return false;
                                }
                        }
@@ -1127,8 +1114,7 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
                        if (m->name == utf_init) {
                                if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
                                                                ACC_NATIVE | ACC_ABSTRACT)) {
-                                       *exceptionptr = new_classformaterror(c,
-                                                       "Instance initialization method has invalid flags set");
+                                       exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
                                        return false;
                                }
                        }
@@ -1136,25 +1122,6 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
        }
 #endif /* ENABLE_VERIFIER */
                
-       m->jcode = NULL;
-       m->basicblockcount = 0;
-       m->basicblocks = NULL;
-       m->basicblockindex = NULL;
-       m->instructioncount = 0;
-       m->instructions = NULL;
-       m->stackcount = 0;
-       m->stack = NULL;
-       m->exceptiontable = NULL;
-       m->stubroutine = NULL;
-       m->mcode = NULL;
-       m->entrypoint = NULL;
-       m->methodUsed = NOTUSED;    
-       m->monoPoly = MONO;    
-       m->subRedefs = 0;
-       m->subRedefsUsed = 0;
-
-       m->xta = NULL;
-
        if (!suck_check_classbuffer_size(cb, 2))
                return false;
        
@@ -1170,17 +1137,12 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
 
                if (aname == utf_Code) {
                        if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
-                                       *exceptionptr =
-                                               new_classformaterror(c,
-                                                                                        "Code attribute in native or abstract methods");
-
-                                       return false;
+                               exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
+                               return false;
                        }
                        
                        if (m->jcode) {
-                               *exceptionptr =
-                                       new_classformaterror(c, "Multiple Code attributes");
-
+                               exceptions_throw_classformaterror(c, "Multiple Code attributes");
                                return false;
                        }
 
@@ -1192,9 +1154,7 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
                        m->maxlocals = suck_u2(cb);
 
                        if (m->maxlocals < argcount) {
-                               *exceptionptr =
-                                       new_classformaterror(c, "Arguments can't fit into locals");
-
+                               exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
                                return false;
                        }
                        
@@ -1204,17 +1164,12 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
                        m->jcodelength = suck_u4(cb);
 
                        if (m->jcodelength == 0) {
-                               *exceptionptr =
-                                       new_classformaterror(c, "Code of a method has length 0");
-
+                               exceptions_throw_classformaterror(c, "Code of a method has length 0");
                                return false;
                        }
                        
                        if (m->jcodelength > 65535) {
-                               *exceptionptr =
-                                       new_classformaterror(c,
-                                                                                "Code of a method longer than 65535 bytes");
-
+                               exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
                                return false;
                        }
 
@@ -1233,7 +1188,7 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
 
                        m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
                        if (opt_stat) {
                                count_vmcode_len += m->jcodelength + 18;
                                count_extable_len +=
@@ -1309,8 +1264,7 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
                        s4 j;
 
                        if (m->thrownexceptions) {
-                               *exceptionptr =
-                                       new_classformaterror(c, "Multiple Exceptions attributes");
+                               exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
                                return false;
                        }
 
@@ -1339,8 +1293,7 @@ static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpoo
        }
 
        if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
-               *exceptionptr = new_classformaterror(c, "Missing Code attribute");
-
+               exceptions_throw_classformaterror(c, "Missing Code attribute");
                return false;
        }
 
@@ -1375,8 +1328,7 @@ static bool load_attributes(classbuffer *cb, u4 num)
                if (aname == utf_InnerClasses) {
                        /* innerclasses attribute */
                        if (c->innerclass) {
-                               *exceptionptr =
-                                       new_classformaterror(c, "Multiple InnerClasses attributes");
+                               exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
                                return false;
                        }
                                
@@ -1418,14 +1370,12 @@ static bool load_attributes(classbuffer *cb, u4 num)
                                return false;
 
                        if (suck_u4(cb) != 2) {
-                               *exceptionptr =
-                                       new_classformaterror(c, "Wrong size for VALUE attribute");
+                               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
                                return false;
                        }
 
                        if (c->sourcefile) {
-                               *exceptionptr =
-                                       new_classformaterror(c, "Multiple SourceFile attributes");
+                               exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
                                return false;
                        }
 
@@ -1475,7 +1425,7 @@ classinfo *load_class_from_sysloader(utf *name)
        if (!m)
                return false;
 
-       cl = (java_objectheader *) asm_calljavafunction(m, NULL, NULL, NULL, NULL);
+       cl = vm_call_method(m, NULL);
 
        if (!cl)
                return false;
@@ -1502,8 +1452,16 @@ classinfo *load_class_from_sysloader(utf *name)
 
 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
 {
-       classinfo *c;
-       classinfo *tmpc;
+       java_objectheader *o;
+       classinfo         *c;
+       classinfo         *tmpc;
+       java_lang_String  *s;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_lookup, time_prepare, time_java, 
+                                       time_cache;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
 
        LOADER_ASSERT(name);
 
@@ -1511,6 +1469,9 @@ classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
 
        c = classcache_lookup(cl, name);
 
+       RT_TIMING_GET_TIME(time_lookup);
+       RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
+
        if (c)
                return c;
 
@@ -1598,10 +1559,17 @@ classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
                if (!lc)
                        return false; /* exception */
 
-               c = (classinfo *) asm_calljavafunction(lc,
-                                                                                          cl,
-                                                                                          javastring_new_slash_to_dot(name),
-                                                                                          NULL, NULL);
+               /* move return value into `o' and cast it afterwards to a classinfo* */
+
+               s = javastring_new_slash_to_dot(name);
+
+               RT_TIMING_GET_TIME(time_prepare);
+
+               o = vm_call_method(lc, cl, s);
+
+               RT_TIMING_GET_TIME(time_java);
+
+               c = (classinfo *) o;
 
                if (c) {
                        /* Store this class in the loaded class cache. If another
@@ -1622,22 +1590,38 @@ classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
                        c = tmpc;
 
                } else {
-                       /* loadClass has thrown an exception */
-                       /* we must convert ClassNotFoundException into NoClassDefFoundException */
-                       /* XXX maybe we should have a flag that avoids this conversion */
-                       /* for calling load_class_from_classloader from Class.forName  */
-                       /* Currently we do a double conversion in these cases          */
+                       /* loadClass has thrown an exception.  We must convert
+                          ClassNotFoundException into
+                          NoClassDefFoundException. */
+
+                       /* XXX Maybe we should have a flag that avoids this
+                          conversion for calling load_class_from_classloader from
+                          Class.forName.  Currently we do a double conversion in
+                          these cases.  */
+
                        classnotfoundexception_to_noclassdeffounderror();
                }
 
+               RT_TIMING_GET_TIME(time_cache);
+
+               RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
+               RT_TIMING_TIME_DIFF(time_prepare, time_java   , RT_TIMING_LOAD_CL_JAVA);
+               RT_TIMING_TIME_DIFF(time_java   , time_cache  , RT_TIMING_LOAD_CL_CACHE);
+
                /* SUN compatible -verbose:class output */
 
                if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
                        printf("[Loaded ");
-                       utf_display_classname(name);
+                       utf_display_printable_ascii_classname(name);
                        printf("]\n");
                }
 
+#if defined(ENABLE_JVMTI)
+               /* fire Class Load JVMTI event */
+               if (jvmti) jvmti_ClassLoadPrepare(false, c);
+#endif
+
+
                return c;
        } 
 
@@ -1669,6 +1653,12 @@ classinfo *load_class_bootstrap(utf *name)
        classbuffer *cb;
        classinfo   *c;
        classinfo   *r;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_lookup, time_array, time_suck, 
+                                       time_load, time_cache;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
 
        /* for debugging */
 
@@ -1676,13 +1666,21 @@ classinfo *load_class_bootstrap(utf *name)
 
        /* lookup if this class has already been loaded */
 
-       if ((r = classcache_lookup(NULL, name)))
+       if ((r = classcache_lookup(NULL, name))) {
+
+               RT_TIMING_GET_TIME(time_lookup);
+               RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
+               
                return r;
+       }
 
+       RT_TIMING_GET_TIME(time_lookup);
+       RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
+               
        /* create the classinfo */
 
        c = class_create_classinfo(name);
-       
+
        /* handle array classes */
 
        if (name->text[0] == '[') {
@@ -1690,16 +1688,20 @@ classinfo *load_class_bootstrap(utf *name)
                if (c == NULL)
                        return NULL;
                LOADER_ASSERT(c->state & CLASS_LOADED);
+
+               RT_TIMING_GET_TIME(time_array);
+               RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
+               
                return c;
        }
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        /* measure time */
 
-       if (getcompilingtime)
+       if (opt_getcompilingtime)
                compilingtime_stop();
 
-       if (getloadingtime)
+       if (opt_getloadingtime)
                loadingtime_start();
 #endif
 
@@ -1716,11 +1718,15 @@ classinfo *load_class_bootstrap(utf *name)
 
                return NULL;
        }
+
+       RT_TIMING_GET_TIME(time_suck);
        
        /* load the class from the buffer */
 
        r = load_class_from_classbuffer(cb);
 
+       RT_TIMING_GET_TIME(time_load);
+       
        if (!r) {
                /* the class could not be loaded, free the classinfo struct */
 
@@ -1741,11 +1747,13 @@ classinfo *load_class_bootstrap(utf *name)
                r = res;
        }
 
+       RT_TIMING_GET_TIME(time_cache);
+       
        /* SUN compatible -verbose:class output */
 
        if (opt_verboseclass && r) {
                printf("[Loaded ");
-               utf_display_classname(name);
+               utf_display_printable_ascii_classname(name);
                printf(" from %s]\n", cb->path);
        }
 
@@ -1753,16 +1761,21 @@ classinfo *load_class_bootstrap(utf *name)
 
        suck_stop(cb);
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        /* measure time */
 
-       if (getloadingtime)
+       if (opt_getloadingtime)
                loadingtime_stop();
 
-       if (getcompilingtime)
+       if (opt_getcompilingtime)
                compilingtime_start();
 #endif
 
+       RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
+       RT_TIMING_TIME_DIFF(time_suck  , time_load , RT_TIMING_LOAD_BOOT_LOAD);
+       RT_TIMING_TIME_DIFF(time_load  , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
+       RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
+
        return r;
 }
 
@@ -1792,10 +1805,18 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
        u4 ma, mi;
        s4 dumpsize;
        descriptor_pool *descpool;
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        u4 classrefsize;
        u4 descsize;
 #endif
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_checks, time_ndpool, time_cpool,
+                                       time_setup, time_fields, time_methods, time_classrefs,
+                                       time_descs,     time_setrefs, time_parsefds, time_parsemds,
+                                       time_parsecpool, time_verify, time_attrs;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
 
        /* get the classbuffer's class */
 
@@ -1806,16 +1827,18 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
        if (c->state & CLASS_LOADED)
                return c;
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        if (opt_stat)
                count_class_loads++;
 #endif
 
+#if !defined(NDEBUG)
        /* output for debugging purposes */
 
        if (loadverbose)
                log_message_class("Loading class: ", c);
-       
+#endif
+
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
@@ -1830,7 +1853,7 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
        /* check signature */
 
        if (suck_u4(cb) != MAGIC) {
-               *exceptionptr = new_classformaterror(c, "Bad magic number");
+               exceptions_throw_classformaterror(c, "Bad magic number");
 
                goto return_exception;
        }
@@ -1848,18 +1871,20 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
 
                goto return_exception;
        }
+       RT_TIMING_GET_TIME(time_checks);
 
        /* create a new descriptor pool */
 
        descpool = descriptor_pool_new(c);
 
+       RT_TIMING_GET_TIME(time_ndpool);
+
        /* load the constant pool */
 
        if (!load_constantpool(cb, descpool))
                goto return_exception;
 
-       c->classUsed = NOTUSED; /* not used initially CO-RT */
-       c->impldBy = NULL;
+       RT_TIMING_GET_TIME(time_cpool);
 
        /* ACC flags */
 
@@ -1879,10 +1904,9 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
                }
 
                if (c->flags & ACC_FINAL) {
-                       *exceptionptr =
-                               new_classformaterror(c,
-                                                                        "Illegal class modifiers: 0x%X", c->flags);
-
+                       exceptions_throw_classformaterror(c,
+                                                                                         "Illegal class modifiers: 0x%X",
+                                                                                         c->flags);
                        goto return_exception;
                }
 
@@ -1892,9 +1916,9 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
        }
 
        if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
-               *exceptionptr =
-                       new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
-
+               exceptions_throw_classformaterror(c,
+                                                                                 "Illegal class modifiers: 0x%X",
+                                                                                 c->flags);
                goto return_exception;
        }
 
@@ -1916,14 +1940,14 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
                char *msg;
                s4    msglen;
 
-               msglen = utf_strlen(c->name) + strlen(" (wrong name: ") +
-                       utf_strlen(name) + strlen(")") + strlen("0");
+               msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
+                       utf_bytes(name) + strlen(")") + strlen("0");
 
                msg = MNEW(char, msglen);
 
-               utf_sprint(msg, c->name);
+               utf_copy_classname(msg, c->name);
                strcat(msg, " (wrong name: ");
-               utf_strcat(msg, name);
+               utf_cat_classname(msg, name);
                strcat(msg, ")");
 
                *exceptionptr =
@@ -1933,7 +1957,7 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
 
                goto return_exception;
        }
-       
+
        /* retrieve superclass */
 
        c->super.any = NULL;
@@ -1968,12 +1992,11 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
                /* This is only allowed for java.lang.Object. */
 
                if (c->name != utf_java_lang_Object) {
-                       *exceptionptr = new_classformaterror(c, "Bad superclass index");
-
+                       exceptions_throw_classformaterror(c, "Bad superclass index");
                        goto return_exception;
                }
        }
-                        
+
        /* retrieve interfaces */
 
        if (!suck_check_classbuffer_size(cb, 2))
@@ -1991,6 +2014,8 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
                        goto return_exception;
        }
 
+       RT_TIMING_GET_TIME(time_setup);
+
        /* load fields */
        if (!suck_check_classbuffer_size(cb, 2))
                goto return_exception;
@@ -2003,6 +2028,8 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
                        goto return_exception;
        }
 
+       RT_TIMING_GET_TIME(time_fields);
+
        /* load methods */
        if (!suck_check_classbuffer_size(cb, 2))
                goto return_exception;
@@ -2010,23 +2037,30 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
        c->methodscount = suck_u2(cb);
 /*     c->methods = GCNEW(methodinfo, c->methodscount); */
        c->methods = MNEW(methodinfo, c->methodscount);
+
+       MZERO(c->methods, methodinfo, c->methodscount);
+       
        for (i = 0; i < c->methodscount; i++) {
                if (!load_method(cb, &(c->methods[i]),descpool))
                        goto return_exception;
        }
 
+       RT_TIMING_GET_TIME(time_methods);
+
        /* create the class reference table */
 
        c->classrefs =
                descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
 
+       RT_TIMING_GET_TIME(time_classrefs);
+
        /* allocate space for the parsed descriptors */
 
        descriptor_pool_alloc_parsed_descriptors(descpool);
        c->parseddescs =
                descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        if (opt_stat) {
                descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
                count_classref_len += classrefsize;
@@ -2034,6 +2068,8 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
        }
 #endif
 
+       RT_TIMING_GET_TIME(time_descs);
+
        /* put the classrefs in the constant pool */
        for (i = 0; i < c->cpcount; i++) {
                if (c->cptags[i] == CONSTANT_Class) {
@@ -2060,6 +2096,8 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
                        goto return_exception;
        }
 
+       RT_TIMING_GET_TIME(time_setrefs);
+
        /* parse field descriptors */
 
        for (i = 0; i < c->fieldscount; i++) {
@@ -2070,6 +2108,8 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
                        goto return_exception;
        }
 
+       RT_TIMING_GET_TIME(time_parsefds);
+
        /* parse method descriptors */
 
        for (i = 0; i < c->methodscount; i++) {
@@ -2098,12 +2138,14 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
                }
        }
 
+       RT_TIMING_GET_TIME(time_parsemds);
+
        /* parse the loaded descriptors */
 
        for (i = 0; i < c->cpcount; i++) {
                constant_FMIref *fmi;
                s4               index;
-               
+
                switch (c->cptags[i]) {
                case CONSTANT_Fieldref:
                        fmi = (constant_FMIref *) c->cpinfos[i];
@@ -2112,33 +2154,35 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
                                                                                                           fmi->descriptor);
                        if (!fmi->parseddesc.fd)
                                goto return_exception;
-                       index = (int) (size_t) fmi->classref;
-                       fmi->classref =
+                       index = fmi->p.index;
+                       fmi->p.classref =
                                (constant_classref *) class_getconstant(c, index,
                                                                                                                CONSTANT_Class);
-                       if (!fmi->classref)
+                       if (!fmi->p.classref)
                                goto return_exception;
                        break;
                case CONSTANT_Methodref:
                case CONSTANT_InterfaceMethodref:
                        fmi = (constant_FMIref *) c->cpinfos[i];
-                       index = (int) (size_t) fmi->classref;
-                       fmi->classref =
+                       index = fmi->p.index;
+                       fmi->p.classref =
                                (constant_classref *) class_getconstant(c, index,
                                                                                                                CONSTANT_Class);
-                       if (!fmi->classref)
+                       if (!fmi->p.classref)
                                goto return_exception;
                        fmi->parseddesc.md =
                                descriptor_pool_parse_method_descriptor(descpool,
                                                                                                                fmi->descriptor,
                                                                                                                ACC_UNDEF,
-                                                                                                               fmi->classref);
+                                                                                                               fmi->p.classref);
                        if (!fmi->parseddesc.md)
                                goto return_exception;
                        break;
                }
        }
 
+       RT_TIMING_GET_TIME(time_parsecpool);
+
 #ifdef ENABLE_VERIFIER
        /* Check if all fields and methods can be uniquely
         * identified by (name,descriptor). */
@@ -2187,17 +2231,14 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
                                do {
                                        if (c->fields[old].name == fi->name &&
                                                c->fields[old].descriptor == fi->descriptor) {
-                                               *exceptionptr =
-                                                       new_classformaterror(c,
-                                                                                                "Repetitive field name/signature");
-
+                                               exceptions_throw_classformaterror(c, "Repetitive field name/signature");
                                                goto return_exception;
                                        }
                                } while ((old = next[old]));
                        }
                        hashtab[index] = i + 1;
                }
-               
+
                /* Check methods */
                memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
 
@@ -2221,26 +2262,25 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
                                do {
                                        if (c->methods[old].name == mi->name &&
                                                c->methods[old].descriptor == mi->descriptor) {
-                                               *exceptionptr =
-                                                       new_classformaterror(c,
-                                                                                                "Repetitive method name/signature");
-
+                                               exceptions_throw_classformaterror(c, "Repetitive method name/signature");
                                                goto return_exception;
                                        }
                                } while ((old = next[old]));
                        }
                        hashtab[index] = i + 1;
                }
-               
+
                MFREE(hashtab, u2, (hashlen + len));
        }
 #endif /* ENABLE_VERIFIER */
 
-#if defined(STATISTICS)
+       RT_TIMING_GET_TIME(time_verify);
+
+#if defined(ENABLE_STATISTICS)
        if (opt_stat) {
-               count_class_infos += sizeof(classinfo*) * c->interfacescount;
-               count_class_infos += sizeof(fieldinfo) * c->fieldscount;
-               count_class_infos += sizeof(methodinfo) * c->methodscount;
+               size_classinfo  += sizeof(classinfo*) * c->interfacescount;
+               size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
+               size_methodinfo += sizeof(methodinfo) * c->methodscount;
        }
 #endif
 
@@ -2252,22 +2292,22 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
        if (!load_attributes(cb, suck_u2(cb)))
                goto return_exception;
 
-#if 0
-       /* Pre java 1.5 version don't check this. This implementation is like
-          java 1.5 do it: for class file version 45.3 we don't check it, older
+       /* Pre Java 1.5 version don't check this. This implementation is like
+          Java 1.5 do it: for class file version 45.3 we don't check it, older
           versions are checked.
         */
-       if ((ma == 45 && mi > 3) || ma > 45) {
+
+       if (((ma == 45) && (mi > 3)) || (ma > 45)) {
                /* check if all data has been read */
                s4 classdata_left = ((cb->data + cb->size) - cb->pos);
 
                if (classdata_left > 0) {
-                       *exceptionptr =
-                               new_classformaterror(c, "Extra bytes at the end of class file");
+                       exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
                        goto return_exception;
                }
        }
-#endif
+
+       RT_TIMING_GET_TIME(time_attrs);
 
        /* release dump area */
 
@@ -2277,8 +2317,33 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
 
        c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
 
+#if defined(ENABLE_JVMTI)
+       /* fire Class Prepare JVMTI event */
+
+       if (jvmti)
+               jvmti_ClassLoadPrepare(true, c);
+#endif
+
+#if !defined(NDEBUG)
        if (loadverbose)
                log_message_class("Loading done class: ", c);
+#endif
+
+       RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
+       RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
+       RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
+       RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
+       RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
+       RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
+       RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
+       RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
+       RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
+       RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
+       RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
+       RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
+       RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
+       RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
+       RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
 
        return c;
 
@@ -2407,12 +2472,12 @@ classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
 
                tc = class_java_lang_Cloneable;
                LOADER_ASSERT(tc->state & CLASS_LOADED);
-               list_addfirst(&unlinkedclasses, tc);
+               list_add_first(&unlinkedclasses, tc);
                c->interfaces[0].cls = tc;
 
                tc = class_java_io_Serializable;
                LOADER_ASSERT(tc->state & CLASS_LOADED);
-               list_addfirst(&unlinkedclasses, tc);
+               list_add_first(&unlinkedclasses, tc);
                c->interfaces[1].cls = tc;
 
        } else {
@@ -2430,7 +2495,7 @@ classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
        /* create descriptor for clone method */
        /* we need one paramslot which is reserved for the 'this' parameter */
        clonedesc = NEW(methoddesc);
-       clonedesc->returntype.type = TYPE_ADDRESS;
+       clonedesc->returntype.type = TYPE_ADR;
        clonedesc->returntype.classref = classrefs + 1;
        clonedesc->returntype.arraydim = 0;
        /* initialize params to "empty", add real params below in
@@ -2438,42 +2503,43 @@ classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
        clonedesc->paramcount = 0;
        clonedesc->paramslots = 0;
        clonedesc->paramtypes[0].classref = classrefs + 0;
+       clonedesc->params = NULL;
 
        /* create methodinfo */
 
        clone = c->methods;
        MSET(clone, 0, methodinfo, 1);
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       initObjectLock(&clone->header);
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(&clone->header);
 #endif
 
-       /* if you delete the ACC_NATIVE below, set clone->maxlocals=1 (interpreter 
-          related) */
-       clone->flags = ACC_PUBLIC | ACC_NATIVE;
-       clone->name = utf_clone;
+       /* ATTENTION: if you delete the ACC_NATIVE below, set
+          clone->maxlocals=1 (interpreter related) */
+
+       clone->flags      = ACC_PUBLIC | ACC_NATIVE;
+       clone->name       = utf_clone;
        clone->descriptor = utf_void__java_lang_Object;
        clone->parseddesc = clonedesc;
-       clone->class = c;
-       clone->monoPoly = MONO;
+       clone->class      = c;
 
        /* parse the descriptor to get the register allocation */
 
        if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
                return false;
 
-       clone->entrypoint =
+       clone->code =
                codegen_createnativestub((functionptr) &builtin_clone_array, clone);
 
        /* XXX: field: length? */
 
        /* array classes are not loaded from class files */
 
-       c->state |= CLASS_LOADED;
-       c->parseddescs = (u1 *) clonedesc;
+       c->state          |= CLASS_LOADED;
+       c->parseddescs    = (u1 *) clonedesc;
        c->parseddescsize = sizeof(methodinfo);
-       c->classrefs = classrefs;
-       c->classrefcount = 1;
+       c->classrefs      = classrefs;
+       c->classrefcount  = 1;
 
        /* insert class into the loaded class cache */
        /* XXX free classinfo if NULL returned? */
@@ -2505,4 +2571,5 @@ void loader_close(void)
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */