* merged with tip (040f180a056b)
authorRobert Schuster <robertschuster@fsfe.org>
Mon, 11 Aug 2008 10:48:32 +0000 (12:48 +0200)
committerRobert Schuster <robertschuster@fsfe.org>
Mon, 11 Aug 2008 10:48:32 +0000 (12:48 +0200)
--HG--
branch : jitcache-arm-x86
rename : src/vmcore/class.c => src/vm/class.c
rename : src/vmcore/class.h => src/vm/class.h
rename : src/vmcore/system.h => src/vm/os.hpp
rename : src/vmcore/references.h => src/vm/references.h
rename : src/vmcore/statistics.c => src/vm/statistics.c
rename : src/vmcore/statistics.h => src/vm/statistics.h

24 files changed:
1  2 
configure.ac
src/vm/builtin.c
src/vm/builtin.h
src/vm/class.c
src/vm/class.h
src/vm/jit/Makefile.am
src/vm/jit/arm/codegen.c
src/vm/jit/arm/patcher.c
src/vm/jit/code.c
src/vm/jit/code.h
src/vm/jit/codegen-common.c
src/vm/jit/i386/codegen.c
src/vm/jit/i386/patcher.c
src/vm/jit/jit.c
src/vm/jit/patcher-common.c
src/vm/jit/patcher-common.h
src/vm/options.c
src/vm/options.h
src/vm/os.hpp
src/vm/references.h
src/vm/resolve.c
src/vm/statistics.c
src/vm/statistics.h
src/vm/vm.cpp

diff --cc configure.ac
Simple merge
Simple merge
Simple merge
diff --cc src/vm/class.c
index 0000000000000000000000000000000000000000,1b547b3bfd74ce0c102d8354642fcafefe02466b..b851c65767f71224481d3fb540b2205ca8bd5d87
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,2472 +1,2481 @@@
+ /* src/vm/class.c - class related functions
+    Copyright (C) 1996-2005, 2006, 2007, 2008
+    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+    This file is part of CACAO.
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2, or (at
+    your option) any later version.
+    This program is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+    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., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+ */
+ #include "config.h"
+ #include <assert.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "vm/types.h"
+ #include "arch.h"
+ #include "mm/memory.h"
+ #include "native/llni.h"
+ #include "threads/lock-common.h"
+ #include "toolbox/logging.h"
+ #include "vm/array.h"
+ #include "vm/builtin.h"
+ #include "vm/class.h"
+ #include "vm/classcache.h"
+ #include "vm/exceptions.hpp"
+ #include "vm/global.h"
+ #include "vm/globals.hpp"
+ #include "vm/javaobjects.hpp"
++#include "vm/jit/jitcache.h"
+ #include "vm/linker.h"
+ #include "vm/loader.h"
+ #include "vm/options.h"
+ #include "vm/resolve.h"
+ #if defined(ENABLE_STATISTICS)
+ # include "vm/statistics.h"
+ #endif
+ #include "vm/suck.h"
+ #include "vm/utf8.h"
+ #include "vm/jit/asmpart.h"
+ /* class_set_packagename *******************************************************
+    Derive the package name from the class name and store it in the
+    struct.
+    An internal package name consists of the package name plus the
+    trailing '/', e.g. "java/lang/".
+    For classes in the unnamed package, the package name is set to
+    NULL.
+ *******************************************************************************/
+ void class_set_packagename(classinfo *c)
+ {
+       char *p;
+       char *start;
+       p     = UTF_END(c->name) - 1;
+       start = c->name->text;
+       if (c->name->text[0] == '[') {
+               /* Set packagename of arrays to the element's package. */
+               for (; *start == '['; start++);
+               /* Skip the 'L' in arrays of references. */
+               if (*start == 'L')
+                       start++;
+       }
+       /* Search for last '/'. */
+       for (; (p > start) && (*p != '/'); --p);
+       /* If we found a '/' we set the package name plus the trailing
+          '/'.  Otherwise we set the packagename to NULL. */
+       if (p > start)
+               c->packagename = utf_new(start, p - start + 1);
+       else
+               c->packagename = NULL;
+ }
+ /* class_create_classinfo ******************************************************
+    Create a new classinfo struct. The class name is set to the given utf *,
+    most other fields are initialized to zero.
+    Note: classname may be NULL. In this case a not-yet-named classinfo is
+          created. The name must be filled in later and class_set_packagename
+                must be called after that.
+ *******************************************************************************/
+ classinfo *class_create_classinfo(utf *classname)
+ {
+       classinfo *c;
+ #if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_classinfo += sizeof(classinfo);
+ #endif
+       /* we use a safe name for temporarily unnamed classes */
+       if (classname == NULL)
+               classname = utf_not_named_yet;
+ #if !defined(NDEBUG)
+       if (initverbose)
+               log_message_utf("Creating class: ", classname);
+ #endif
+ #if !defined(ENABLE_GC_BOEHM)
+       c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
+       /*c = NEW(classinfo);
+       MZERO(c, classinfo, 1);*/
+ #else
+       c = GCNEW_UNCOLLECTABLE(classinfo, 1);
+       /* GCNEW_UNCOLLECTABLE clears the allocated memory */
+ #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 != 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_REFERENCE_SOFT;
+       }
+       else if (classname == utf_java_lang_ref_WeakReference) {
+               c->flags |= ACC_CLASS_REFERENCE_WEAK;
+       }
+       else if (classname == utf_java_lang_ref_PhantomReference) {
+               c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
+       }
+ #endif
+       if (classname != utf_not_named_yet)
+               class_set_packagename(c);
++#if defined (ENABLE_JITCACHE)
++    c->cache_file_fd = 0;
++#endif
+       LOCK_INIT_OBJECT_LOCK(&c->object.header);
+       return c;
+ }
+ /* class_postset_header_vftbl **************************************************
+    Set the header.vftbl of all classes created before java.lang.Class
+    was linked.  This is necessary that Java code can use a class as
+    object.
+ *******************************************************************************/
+ void class_postset_header_vftbl(void)
+ {
+       classinfo *c;
+       u4 slot;
+       classcache_name_entry *nmen;
+       classcache_class_entry *clsen;
+       assert(class_java_lang_Class);
+       for (slot = 0; slot < hashtable_classcache.size; slot++) {
+               nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
+               for (; nmen; nmen = nmen->hashlink) {
+                       /* iterate over all class entries */
+                       for (clsen = nmen->classes; clsen; clsen = clsen->next) {
+                               c = clsen->classobj;
+                               /* now set the the vftbl */
+                               if (c->object.header.vftbl == NULL)
+                                       c->object.header.vftbl = class_java_lang_Class->vftbl;
+                       }
+               }
+       }
+ }
+ /* class_define ****************************************************************
+    Calls the loader and defines a class in the VM.
+ *******************************************************************************/
+ classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
+ {
+       classinfo   *c;
+       classinfo   *r;
+       classbuffer *cb;
+       if (name != NULL) {
+               /* check if this class has already been defined */
+               c = classcache_lookup_defined_or_initiated(cl, name);
+               if (c != NULL) {
+                       exceptions_throw_linkageerror("duplicate class definition: ", c);
+                       return NULL;
+               }
+       } 
+       /* create a new classinfo struct */
+       c = class_create_classinfo(name);
+ #if defined(ENABLE_STATISTICS)
+       /* measure time */
+       if (opt_getloadingtime)
+               loadingtime_start();
+ #endif
+       /* build a classbuffer with the given data */
+       cb = NEW(classbuffer);
+       cb->clazz = c;
+       cb->size  = length;
+       cb->data  = data;
+       cb->pos   = cb->data;
+       /* preset the defining classloader */
+       c->classloader = cl;
+       /* load the class from this buffer */
+       r = load_class_from_classbuffer(cb);
+       /* free memory */
+       FREE(cb, classbuffer);
+ #if defined(ENABLE_STATISTICS)
+       /* measure time */
+       if (opt_getloadingtime)
+               loadingtime_stop();
+ #endif
+       if (r == NULL) {
+               /* If return value is NULL, we had a problem and the class is
+                  not loaded.  Now free the allocated memory, otherwise we
+                  could run into a DOS. */
+               class_free(c);
+               return NULL;
+       }
+ #if defined(ENABLE_JAVASE)
+ # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       /* Store the protection domain. */
+       c->protectiondomain = pd;
+ # endif
+ #endif
+       /* Store the newly defined class in the class cache. This call
+          also checks whether a class of the same name has already been
+          defined by the same defining loader, and if so, replaces the
+          newly created class by the one defined earlier. */
+       /* Important: The classinfo given to classcache_store must be
+                     fully prepared because another thread may return
+                     this pointer after the lookup at to top of this
+                     function directly after the class cache lock has
+                     been released. */
+       c = classcache_store(cl, c, true);
+       return c;
+ }
+ /* class_load_attribute_sourcefile *********************************************
+    SourceFile_attribute {
+        u2 attribute_name_index;
+        u4 attribute_length;
+          u2 sourcefile_index;
+    }
+ *******************************************************************************/
+ static bool class_load_attribute_sourcefile(classbuffer *cb)
+ {
+       classinfo *c;
+       u4         attribute_length;
+       u2         sourcefile_index;
+       utf       *sourcefile;
+       /* get classinfo */
+       c = cb->clazz;
+       /* check buffer size */
+       if (!suck_check_classbuffer_size(cb, 4 + 2))
+               return false;
+       /* check attribute length */
+       attribute_length = suck_u4(cb);
+       if (attribute_length != 2) {
+               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+               return false;
+       }
+       /* there can be no more than one SourceFile attribute */
+       if (c->sourcefile != NULL) {
+               exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
+               return false;
+       }
+       /* get sourcefile */
+       sourcefile_index = suck_u2(cb);
+       sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
+       if (sourcefile == NULL)
+               return false;
+       /* store sourcefile */
+       c->sourcefile = sourcefile;
+       return true;
+ }
+ /* class_load_attribute_enclosingmethod ****************************************
+    EnclosingMethod_attribute {
+        u2 attribute_name_index;
+        u4 attribute_length;
+          u2 class_index;
+          u2 method_index;
+    }
+ *******************************************************************************/
+ #if defined(ENABLE_JAVASE)
+ static bool class_load_attribute_enclosingmethod(classbuffer *cb)
+ {
+       classinfo             *c;
+       u4                     attribute_length;
+       u2                     class_index;
+       u2                     method_index;
+       classref_or_classinfo  cr;
+       constant_nameandtype  *cn;
+       /* get classinfo */
+       c = cb->clazz;
+       /* check buffer size */
+       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
+               return false;
+       /* check attribute length */
+       attribute_length = suck_u4(cb);
+       if (attribute_length != 4) {
+               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+               return false;
+       }
+       /* there can be no more than one EnclosingMethod attribute */
+       if (c->enclosingmethod != NULL) {
+               exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
+               return false;
+       }
+       /* get class index */
+       class_index = suck_u2(cb);
+       cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
+       /* get method index */
+       method_index = suck_u2(cb);
+       cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
+       /* store info in classinfo */
+       c->enclosingclass.any = cr.any;
+       c->enclosingmethod    = cn;
+       return true;
+ }
+ #endif /* defined(ENABLE_JAVASE) */
+ /* class_load_attributes *******************************************************
+    Read attributes from ClassFile.
+    attribute_info {
+        u2 attribute_name_index;
+        u4 attribute_length;
+        u1 info[attribute_length];
+    }
+    InnerClasses_attribute {
+        u2 attribute_name_index;
+        u4 attribute_length;
+    }
+ *******************************************************************************/
+ bool class_load_attributes(classbuffer *cb)
+ {
+       classinfo             *c;
+       uint16_t               attributes_count;
+       uint16_t               attribute_name_index;
+       utf                   *attribute_name;
+       innerclassinfo        *info;
+       classref_or_classinfo  inner;
+       classref_or_classinfo  outer;
+       utf                   *name;
+       uint16_t               flags;
+       int                    i, j;
+       c = cb->clazz;
+       /* get attributes count */
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+       attributes_count = suck_u2(cb);
+       for (i = 0; i < attributes_count; i++) {
+               /* get attribute name */
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+               attribute_name_index = suck_u2(cb);
+               attribute_name =
+                       class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
+               if (attribute_name == NULL)
+                       return false;
+               if (attribute_name == utf_InnerClasses) {
+                       /* InnerClasses */
+                       if (c->innerclass != NULL) {
+                               exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
+                               return false;
+                       }
+                               
+                       if (!suck_check_classbuffer_size(cb, 4 + 2))
+                               return false;
+                       /* skip attribute length */
+                       suck_u4(cb);
+                       /* number of records */
+                       c->innerclasscount = suck_u2(cb);
+                       if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
+                               return false;
+                       /* allocate memory for innerclass structure */
+                       c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
+                       for (j = 0; j < c->innerclasscount; j++) {
+                               /* The innerclass structure contains a class with an encoded
+                                  name, its defining scope, its simple name and a bitmask of
+                                  the access flags. */
+                                                               
+                               info = c->innerclass + j;
+                               inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
+                               outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
+                               name      = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
+                               flags     = suck_u2(cb);
+                               /* If the current inner-class is the currently loaded
+                                  class check for some special flags. */
+                               if (inner.ref->name == c->name) {
+                                       /* If an inner-class is not a member, its
+                                          outer-class is NULL. */
+                                       if (outer.ref != NULL) {
+                                               c->flags |= ACC_CLASS_MEMBER;
+                                               /* A member class doesn't have an
+                                                  EnclosingMethod attribute, so set the
+                                                  enclosing-class to be the same as the
+                                                  declaring-class. */
+                                               c->declaringclass = outer;
+                                               c->enclosingclass = outer;
+                                       }
+                                       /* If an inner-class is anonymous, its name is
+                                          NULL. */
+                                       if (name == NULL)
+                                               c->flags |= ACC_CLASS_ANONYMOUS;
+                               }
+                               info->inner_class = inner;
+                               info->outer_class = outer;
+                               info->name        = name;
+                               info->flags       = flags;
+                       }
+               }
+               else if (attribute_name == utf_SourceFile) {
+                       /* SourceFile */
+                       if (!class_load_attribute_sourcefile(cb))
+                               return false;
+               }
+ #if defined(ENABLE_JAVASE)
+               else if (attribute_name == utf_EnclosingMethod) {
+                       /* EnclosingMethod */
+                       if (!class_load_attribute_enclosingmethod(cb))
+                               return false;
+               }
+               else if (attribute_name == utf_Signature) {
+                       /* Signature */
+                       if (!loader_load_attribute_signature(cb, &(c->signature)))
+                               return false;
+               }
+ #endif
+ #if defined(ENABLE_ANNOTATIONS)
+               else if (attribute_name == utf_RuntimeVisibleAnnotations) {
+                       /* RuntimeVisibleAnnotations */
+                       if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
+                               return false;
+               }
+               else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
+                       /* RuntimeInvisibleAnnotations */
+                       if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
+                               return false;
+               }
+ #endif
+               else {
+                       /* unknown attribute */
+                       if (!loader_skip_attribute_body(cb))
+                               return false;
+               }
+       }
+       return true;
+ }
+ /* class_freepool **************************************************************
+       Frees all resources used by this classes Constant Pool.
+ *******************************************************************************/
+ static void class_freecpool(classinfo *c)
+ {
+       u4 idx;
+       u4 tag;
+       void* info;
+       
+       if (c->cptags && c->cpinfos) {
+               for (idx = 0; idx < c->cpcount; idx++) {
+                       tag = c->cptags[idx];
+                       info = c->cpinfos[idx];
+               
+                       if (info != NULL) {
+                               switch (tag) {
+                               case CONSTANT_Fieldref:
+                               case CONSTANT_Methodref:
+                               case CONSTANT_InterfaceMethodref:
+                                       FREE(info, constant_FMIref);
+                                       break;
+                               case CONSTANT_Integer:
+                                       FREE(info, constant_integer);
+                                       break;
+                               case CONSTANT_Float:
+                                       FREE(info, constant_float);
+                                       break;
+                               case CONSTANT_Long:
+                                       FREE(info, constant_long);
+                                       break;
+                               case CONSTANT_Double:
+                                       FREE(info, constant_double);
+                                       break;
+                               case CONSTANT_NameAndType:
+                                       FREE(info, constant_nameandtype);
+                                       break;
+                               }
+                       }
+               }
+       }
+       if (c->cptags)
+               MFREE(c->cptags, u1, c->cpcount);
+       if (c->cpinfos)
+               MFREE(c->cpinfos, void*, c->cpcount);
+ }
+ /* class_getconstant ***********************************************************
+    Retrieves the value at position 'pos' of the constantpool of a
+    class. If the type of the value is other than 'ctype', an error is
+    thrown.
+ *******************************************************************************/
+ void* class_getconstant(classinfo *c, u4 pos, u4 ctype)
+ {
+       /* check index and type of constantpool entry */
+       /* (pos == 0 is caught by type comparison) */
+       if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool index");
+               return NULL;
+       }
+       return c->cpinfos[pos];
+ }
+ /* innerclass_getconstant ******************************************************
+    Like class_getconstant, but if cptags is ZERO, null is returned.
+       
+ *******************************************************************************/
+ void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
+ {
+       /* invalid position in constantpool */
+       if (pos >= c->cpcount) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool index");
+               return NULL;
+       }
+       /* constantpool entry of type 0 */      
+       if (c->cptags[pos] == 0)
+               return NULL;
+       /* check type of constantpool entry */
+       if (c->cptags[pos] != ctype) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool index");
+               return NULL;
+       }
+               
+       return c->cpinfos[pos];
+ }
+ /* class_free ******************************************************************
+    Frees all resources used by the class.
+ *******************************************************************************/
+ void class_free(classinfo *c)
+ {
+       s4 i;
+       vftbl_t *v;
++#if defined(ENABLE_JITCACHE)
++/* TODO: Find a way around the linker problem */
++/*    jitcache_freeclass(c);*/
++#endif
++
+       class_freecpool(c);
+       if (c->interfaces != NULL)
+               MFREE(c->interfaces, classinfo*, c->interfacescount);
+       if (c->fields) {
+               for (i = 0; i < c->fieldscount; i++)
+                       field_free(&(c->fields[i]));
+               MFREE(c->fields, fieldinfo, c->fieldscount);
+       }
+       
+       if (c->methods) {
+               for (i = 0; i < c->methodscount; i++)
+                       method_free(&(c->methods[i]));
+               MFREE(c->methods, methodinfo, c->methodscount);
+       }
+       if ((v = c->vftbl) != NULL) {
+               if (v->arraydesc)
+                       mem_free(v->arraydesc,sizeof(arraydescriptor));
+               
+               for (i = 0; i < v->interfacetablelength; i++) {
+                       MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
+               }
+               MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
+               i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
+                   sizeof(methodptr*) * (v->interfacetablelength -
+                                        (v->interfacetablelength > 0));
+               v = (vftbl_t*) (((methodptr*) v) -
+                                               (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
+               mem_free(v, i);
+       }
+       if (c->innerclass)
+               MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
+       /*      if (c->classvftbl)
+               mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
+       
+ /*    GCFREE(c); */
+ }
+ /* get_array_class *************************************************************
+    Returns the array class with the given name for the given
+    classloader, or NULL if an exception occurred.
+    Note: This function does eager loading. 
+ *******************************************************************************/
+ static classinfo *get_array_class(utf *name,classloader_t *initloader,
+                                                                                       classloader_t *defloader,bool link)
+ {
+       classinfo *c;
+       
+       /* lookup this class in the classcache */
+       c = classcache_lookup(initloader,name);
+       if (!c)
+               c = classcache_lookup_defined(defloader,name);
+       if (!c) {
+               /* we have to create it */
+               c = class_create_classinfo(name);
+               c = load_newly_created_array(c,initloader);
+               if (c == NULL)
+                       return NULL;
+       }
+       assert(c);
+       assert(c->state & CLASS_LOADED);
+       assert(c->classloader == defloader);
+       if (link && !(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return NULL;
+       assert(!link || (c->state & CLASS_LINKED));
+       return c;
+ }
+ /* class_array_of **************************************************************
+    Returns an array class with the given component class. The array
+    class is dynamically created if neccessary.
+ *******************************************************************************/
+ classinfo *class_array_of(classinfo *component, bool link)
+ {
+       classloader_t     *cl;
+     s4                 namelen;
+     char              *namebuf;
+       utf               *u;
+       classinfo         *c;
+       int32_t            dumpmarker;
+       cl = component->classloader;
+       DMARKER;
+     /* Assemble the array class name */
+     namelen = component->name->blength;
+     
+     if (component->name->text[0] == '[') {
+         /* the component is itself an array */
+         namebuf = DMNEW(char, namelen + 1);
+         namebuf[0] = '[';
+         MCOPY(namebuf + 1, component->name->text, char, namelen);
+         namelen++;
+     }
+       else {
+         /* the component is a non-array class */
+         namebuf = DMNEW(char, namelen + 3);
+         namebuf[0] = '[';
+         namebuf[1] = 'L';
+         MCOPY(namebuf + 2, component->name->text, char, namelen);
+         namebuf[2 + namelen] = ';';
+         namelen += 3;
+     }
+       u = utf_new(namebuf, namelen);
+       c = get_array_class(u, cl, cl, link);
+       DRELEASE;
+       return c;
+ }
+ /* class_multiarray_of *********************************************************
+    Returns an array class with the given dimension and element class.
+    The array class is dynamically created if neccessary.
+ *******************************************************************************/
+ classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
+ {
+     s4 namelen;
+     char *namebuf;
+       classinfo *c;
+       int32_t    dumpmarker;
+       DMARKER;
+       if (dim < 1) {
+               log_text("Invalid array dimension requested");
+               assert(0);
+       }
+     /* Assemble the array class name */
+     namelen = element->name->blength;
+     
+     if (element->name->text[0] == '[') {
+         /* the element is itself an array */
+         namebuf = DMNEW(char, namelen + dim);
+         memcpy(namebuf + dim, element->name->text, namelen);
+         namelen += dim;
+     }
+     else {
+         /* the element is a non-array class */
+         namebuf = DMNEW(char, namelen + 2 + dim);
+         namebuf[dim] = 'L';
+         memcpy(namebuf + dim + 1, element->name->text, namelen);
+         namelen += (2 + dim);
+         namebuf[namelen - 1] = ';';
+     }
+       memset(namebuf, '[', dim);
+       c = get_array_class(utf_new(namebuf, namelen),
+                                               element->classloader,
+                                               element->classloader,
+                                               link);
+       DRELEASE;
+       return c;
+ }
+ /* class_lookup_classref *******************************************************
+    Looks up the constant_classref for a given classname in the classref
+    tables of a class.
+    IN:
+        cls..............the class containing the reference
+          name.............the name of the class refered to
+     RETURN VALUE:
+          a pointer to a constant_classref, or 
+          NULL if the reference was not found
+    
+ *******************************************************************************/
+ constant_classref *class_lookup_classref(classinfo *cls, utf *name)
+ {
+       constant_classref *ref;
+       extra_classref *xref;
+       int count;
+       assert(cls);
+       assert(name);
+       assert(!cls->classrefcount || cls->classrefs);
+       
+       /* first search the main classref table */
+       count = cls->classrefcount;
+       ref = cls->classrefs;
+       for (; count; --count, ++ref)
+               if (ref->name == name)
+                       return ref;
+       /* next try the list of extra classrefs */
+       for (xref = cls->extclassrefs; xref; xref = xref->next) {
+               if (xref->classref.name == name)
+                       return &(xref->classref);
+       }
+       /* not found */
+       return NULL;
+ }
+ /* class_get_classref **********************************************************
+    Returns the constant_classref for a given classname.
+    IN:
+        cls..............the class containing the reference
+          name.............the name of the class refered to
+    RETURN VALUE:
+        a pointer to a constant_classref (never NULL)
+    NOTE:
+        The given name is not checked for validity!
+    
+ *******************************************************************************/
+ constant_classref *class_get_classref(classinfo *cls, utf *name)
+ {
+       constant_classref *ref;
+       extra_classref *xref;
+       assert(cls);
+       assert(name);
+       ref = class_lookup_classref(cls,name);
+       if (ref)
+               return ref;
+       xref = NEW(extra_classref);
+       CLASSREF_INIT(xref->classref,cls,name);
+       xref->next = cls->extclassrefs;
+       cls->extclassrefs = xref;
+       return &(xref->classref);
+ }
+ /* class_get_self_classref *****************************************************
+    Returns the constant_classref to the class itself.
+    IN:
+        cls..............the class containing the reference
+    RETURN VALUE:
+        a pointer to a constant_classref (never NULL)
+ *******************************************************************************/
+ constant_classref *class_get_self_classref(classinfo *cls)
+ {
+       /* XXX this should be done in a faster way. Maybe always make */
+       /* the classref of index 0 a self reference.                  */
+       return class_get_classref(cls,cls->name);
+ }
+ /* class_get_classref_multiarray_of ********************************************
+    Returns an array type reference with the given dimension and element class
+    reference.
+    IN:
+        dim..............the requested dimension
+                           dim must be in [1;255]. This is NOT checked!
+          ref..............the component class reference
+    RETURN VALUE:
+        a pointer to the class reference for the array type
+    NOTE:
+        The referer of `ref` is used as the referer for the new classref.
+ *******************************************************************************/
+ constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
+ {
+     s4 namelen;
+     char *namebuf;
+       constant_classref *cr;
+       int32_t            dumpmarker;
+       assert(ref);
+       assert(dim >= 1 && dim <= 255);
+       DMARKER;
+     /* Assemble the array class name */
+     namelen = ref->name->blength;
+     
+     if (ref->name->text[0] == '[') {
+         /* the element is itself an array */
+         namebuf = DMNEW(char, namelen + dim);
+         memcpy(namebuf + dim, ref->name->text, namelen);
+         namelen += dim;
+     }
+     else {
+         /* the element is a non-array class */
+         namebuf = DMNEW(char, namelen + 2 + dim);
+         namebuf[dim] = 'L';
+         memcpy(namebuf + dim + 1, ref->name->text, namelen);
+         namelen += (2 + dim);
+         namebuf[namelen - 1] = ';';
+     }
+       memset(namebuf, '[', dim);
+     cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
+       DRELEASE;
+       return cr;
+ }
+ /* class_get_classref_component_of *********************************************
+    Returns the component classref of a given array type reference
+    IN:
+        ref..............the array type reference
+    RETURN VALUE:
+        a reference to the component class, or
+          NULL if `ref` is not an object array type reference
+    NOTE:
+        The referer of `ref` is used as the referer for the new classref.
+ *******************************************************************************/
+ constant_classref *class_get_classref_component_of(constant_classref *ref)
+ {
+       s4 namelen;
+       char *name;
+       
+       assert(ref);
+       name = ref->name->text;
+       if (*name++ != '[')
+               return NULL;
+       
+       namelen = ref->name->blength - 1;
+       if (*name == 'L') {
+               name++;
+               namelen -= 2;
+       }
+       else if (*name != '[') {
+               return NULL;
+       }
+     return class_get_classref(ref->referer, utf_new(name, namelen));
+ }
+ /* class_findmethod ************************************************************
+       
+    Searches a 'classinfo' structure for a method having the given name
+    and descriptor. If descriptor is NULL, it is ignored.
+ *******************************************************************************/
+ methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
+ {
+       methodinfo *m;
+       s4          i;
+       for (i = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+               if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
+                       return m;
+       }
+       return NULL;
+ }
+ /* class_resolvemethod *********************************************************
+       
+    Searches a class and it's super classes for a method.
+    Superinterfaces are *not* searched.
+ *******************************************************************************/
+ methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
+ {
+       methodinfo *m;
+       while (c) {
+               m = class_findmethod(c, name, desc);
+               if (m)
+                       return m;
+               /* JVM Specification bug: 
+                  It is important NOT to resolve special <init> and <clinit>
+                  methods to super classes or interfaces; yet, this is not
+                  explicited in the specification.  Section 5.4.3.3 should be
+                  updated appropriately.  */
+               if (name == utf_init || name == utf_clinit)
+                       return NULL;
+               c = c->super;
+       }
+       return NULL;
+ }
+ /* class_resolveinterfacemethod_intern *****************************************
+    Internally used helper function. Do not use this directly.
+ *******************************************************************************/
+ static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
+                                                                                                          utf *name, utf *desc)
+ {
+       methodinfo *m;
+       s4          i;
+       /* try to find the method in the class */
+       m = class_findmethod(c, name, desc);
+       if (m != NULL)
+               return m;
+       /* No method found?  Try the super interfaces. */
+       for (i = 0; i < c->interfacescount; i++) {
+               m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
+               if (m != NULL)
+                       return m;
+       }
+       /* no method found */
+       return NULL;
+ }
+ /* class_resolveclassmethod ****************************************************
+       
+    Resolves a reference from REFERER to a method with NAME and DESC in
+    class C.
+    If the method cannot be resolved the return value is NULL. If
+    EXCEPT is true *exceptionptr is set, too.
+ *******************************************************************************/
+ methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
+                                                                        classinfo *referer, bool throwexception)
+ {
+       classinfo  *cls;
+       methodinfo *m;
+       s4          i;
+ /*    if (c->flags & ACC_INTERFACE) { */
+ /*            if (throwexception) */
+ /*                    *exceptionptr = */
+ /*                            new_exception(string_java_lang_IncompatibleClassChangeError); */
+ /*            return NULL; */
+ /*    } */
+       /* try class c and its superclasses */
+       cls = c;
+       m = class_resolvemethod(cls, name, desc);
+       if (m != NULL)
+               goto found;
+       /* Try the super interfaces. */
+       for (i = 0; i < c->interfacescount; i++) {
+               m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
+               if (m != NULL)
+                       goto found;
+       }
+       
+       if (throwexception)
+               exceptions_throw_nosuchmethoderror(c, name, desc);
+       return NULL;
+  found:
+       if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
+               if (throwexception)
+                       exceptions_throw_abstractmethoderror();
+               return NULL;
+       }
+       /* XXX check access rights */
+       return m;
+ }
+ /* class_resolveinterfacemethod ************************************************
+    Resolves a reference from REFERER to a method with NAME and DESC in
+    interface C.
+    If the method cannot be resolved the return value is NULL. If
+    EXCEPT is true *exceptionptr is set, too.
+ *******************************************************************************/
+ methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
+                                                                                classinfo *referer, bool throwexception)
+ {
+       methodinfo *mi;
+       if (!(c->flags & ACC_INTERFACE)) {
+               if (throwexception)
+                       exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
+               return NULL;
+       }
+       mi = class_resolveinterfacemethod_intern(c, name, desc);
+       if (mi != NULL)
+               return mi;
+       /* try class java.lang.Object */
+       mi = class_findmethod(class_java_lang_Object, name, desc);
+       if (mi != NULL)
+               return mi;
+       if (throwexception)
+               exceptions_throw_nosuchmethoderror(c, name, desc);
+       return NULL;
+ }
+ /* class_findfield *************************************************************
+       
+    Searches for field with specified name and type in a classinfo
+    structure. If no such field is found NULL is returned.
+ *******************************************************************************/
+ fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
+ {
+       s4 i;
+       for (i = 0; i < c->fieldscount; i++)
+               if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
+                       return &(c->fields[i]);
+       if (c->super != NULL)
+               return class_findfield(c->super, name, desc);
+       return NULL;
+ }
+ /* class_findfield_approx ******************************************************
+       
+    Searches in 'classinfo'-structure for a field with the specified
+    name.
+ *******************************************************************************/
+  
+ fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
+ {
+       for (int32_t i = 0; i < c->fieldscount; i++) {
+               fieldinfo* f = &(c->fields[i]);
+               if (f->name == name)
+                       return f;
+       }
+       // Field not found.
+       exceptions_throw_nosuchfielderror(c, name);
+       return NULL;
+ }
+ /****************** Function: class_resolvefield_int ***************************
+     This is an internally used helper function. Do not use this directly.
+       Tries to resolve a field having the given name and type.
+     If the field cannot be resolved, NULL is returned.
+ *******************************************************************************/
+ static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
+ {
+       fieldinfo *fi;
+       s4         i;
+       /* search for field in class c */
+       for (i = 0; i < c->fieldscount; i++) { 
+               if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
+                       return &(c->fields[i]);
+               }
+     }
+       /* Try super interfaces recursively. */
+       for (i = 0; i < c->interfacescount; i++) {
+               fi = class_resolvefield_int(c->interfaces[i], name, desc);
+               if (fi != NULL)
+                       return fi;
+       }
+       /* Try super class. */
+       if (c->super != NULL)
+               return class_resolvefield_int(c->super, name, desc);
+       /* not found */
+       return NULL;
+ }
+ /********************* Function: class_resolvefield ***************************
+       
+       Resolves a reference from REFERER to a field with NAME and DESC in class C.
+     If the field cannot be resolved, an exception is thrown and the
+     return value is NULL.
+ *******************************************************************************/
+ fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
+ {
+       fieldinfo *fi;
+       fi = class_resolvefield_int(c, name, desc);
+       if (!fi) {
+               exceptions_throw_nosuchfielderror(c, name);
+               return NULL;
+       }
+       /* XXX check access rights */
+       return fi;
+ }
+ /* class_issubclass ************************************************************
+    Checks if sub is a descendant of super.
+       
+ *******************************************************************************/
+ bool class_issubclass(classinfo *sub, classinfo *super)
+ {
+       classinfo *c;
+       c = sub;
+       for (;;) {
+               /* We reached java/lang/Object and did not find the requested
+                  super class. */
+               if (c == NULL)
+                       return false;
+               /* We found the requested super class. */
+               if (c == super)
+                       return true;
+               c = c->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)
+ {
+       uint32_t diffval;
+       bool     result;
+       /* This is the trivial case. */
+       if (sub == super)
+               return true;
+       /* Primitive classes are only subclasses of themselves. */
+       if (class_is_primitive(sub) || class_is_primitive(super))
+               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);
+               LOCK_MONITOR_ENTER(linker_classrenumber_lock);
+               diffval = sub->vftbl->baseval - super->vftbl->baseval;
+               result  = diffval <= (uint32_t) super->vftbl->diffval;
+               LOCK_MONITOR_EXIT(linker_classrenumber_lock);
+       }
+       return result;
+ }
+ /* class_is_assignable_from ****************************************************
+    Return whether an instance of the "from" class parameter would be
+    an instance of this class "to" as well.
+    ARGUMENTS:
+        to ..... class
+          from ... class
+    RETURN:
+        true .... is assignable
+          false ... is not assignable
+ *******************************************************************************/
+ bool class_is_assignable_from(classinfo *to, classinfo *from)
+ {
+       if (!(to->state & CLASS_LINKED))
+               if (!link_class(to))
+                       return false;
+       if (!(from->state & CLASS_LINKED))
+               if (!link_class(from))
+                       return false;
+       return class_isanysubclass(from, to);
+ }
+ /* class_is_instance ***********************************************************
+    Return if the given Java object is an instance of the given class.
+    ARGUMENTS:
+        c ... class
+          h ... Java object
+    RETURN:
+        true .... is instance
+          false ... is not instance
+ *******************************************************************************/
+ bool class_is_instance(classinfo *c, java_handle_t *h)
+ {
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return false;
+       return builtin_instanceof(h, c);
+ }
+ /* class_get_componenttype *****************************************************
+    Return the component class of the given class.  If the given class
+    is not an array, return NULL.
+ *******************************************************************************/
+ classinfo *class_get_componenttype(classinfo *c)
+ {
+       classinfo       *component;
+       arraydescriptor *ad;
+       
+       /* XXX maybe we could find a way to do this without linking. */
+       /* This way should be safe and easy, however.                */
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return NULL;
+       ad = c->vftbl->arraydesc;
+       
+       if (ad == NULL)
+               return NULL;
+       
+       if (ad->arraytype == ARRAYTYPE_OBJECT)
+               component = ad->componentvftbl->clazz;
+       else
+               component = Primitive_get_class_by_type(ad->arraytype);
+               
+       return component;
+ }
+ /* class_get_declaredclasses ***************************************************
+    Return an array of declared classes of the given class.
+ *******************************************************************************/
+ java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
+ {
+       classref_or_classinfo  inner;
+       classref_or_classinfo  outer;
+       utf                   *outername;
+       int                    declaredclasscount;  /* number of declared classes */
+       int                    pos;                     /* current declared class */
+       java_handle_objectarray_t *oa;               /* array of declared classes */
+       int                    i;
+       classinfo             *ic;
+       declaredclasscount = 0;
+       if (!class_is_primitive(c) && !class_is_array(c)) {
+               /* Determine number of declared classes. */
+               for (i = 0; i < c->innerclasscount; i++) {
+                       /* Get outer-class.  If the inner-class is not a member
+                          class, the outer-class is NULL. */
+                       outer = c->innerclass[i].outer_class;
+                       if (outer.any == NULL)
+                               continue;
+                       /* Check if outer-class is a classref or a real class and
+                get the class name from the structure. */
+                       outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
+                       /* Outer class is this class. */
+                       if ((outername == c->name) &&
+                               ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
+                               declaredclasscount++;
+               }
+       }
+       /* Allocate Class[] and check for OOM. */
+       oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
+       if (oa == NULL)
+               return NULL;
+       for (i = 0, pos = 0; i < c->innerclasscount; i++) {
+               inner = c->innerclass[i].inner_class;
+               outer = c->innerclass[i].outer_class;
+               /* Get outer-class.  If the inner-class is not a member class,
+                  the outer-class is NULL. */
+               if (outer.any == NULL)
+                       continue;
+               /* Check if outer_class is a classref or a real class and get
+                  the class name from the structure. */
+               outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
+               /* Outer class is this class. */
+               if ((outername == c->name) &&
+                       ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
+                       ic = resolve_classref_or_classinfo_eager(inner, false);
+                       if (ic == NULL)
+                               return NULL;
+                       if (!(ic->state & CLASS_LINKED))
+                               if (!link_class(ic))
+                                       return NULL;
+                       LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
+               }
+       }
+       return oa;
+ }
+ /**
+  * Return an array of declared constructors of the given class.
+  *
+  * @param c          class to get the constructors of
+  * @param publicOnly show only public fields
+  *
+  * @return array of java.lang.reflect.Constructor
+  */
+ #if defined(ENABLE_JAVASE)
+ java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
+ {
+       methodinfo*                m;
+       java_handle_objectarray_t* oa;
+       java_handle_t*             rc;
+       int                        count;
+       int                        index;
+       int                        i;
+       /* Determine number of constructors. */
+       count = 0;
+       for (i = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+                       (m->name == utf_init))
+                       count++;
+       }
+       /* Create array of constructors. */
+       oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
+       if (oa == NULL)
+               return NULL;
+       /* Get the constructors and store them in the array. */
+       for (i = 0, index = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+                       (m->name == utf_init)) {
+                       // Create a java.lang.reflect.Constructor object.
+                       rc = java_lang_reflect_Constructor_create(m);
+                       /* Store object into array. */
+                       array_objectarray_element_set(oa, index, rc);
+                       index++;
+               }
+       }
+       return oa;
+ }
+ #endif
+ /* class_get_declaredfields ****************************************************
+    Return an array of declared fields of the given class.
+    ARGUMENTS:
+        c ............ class to get the fields of
+          publicOnly ... show only public fields
+    RETURN:
+        array of java.lang.reflect.Field
+ *******************************************************************************/
+ #if defined(ENABLE_JAVASE)
+ java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
+ {
+       java_handle_objectarray_t *oa;
+       fieldinfo                 *f;
+       java_handle_t             *h;
+       int                        count;
+       int                        index;
+       int                        i;
+       /* Determine number of fields. */
+       count = 0;
+       for (i = 0; i < c->fieldscount; i++)
+               if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
+                       count++;
+       /* Create array of fields. */
+       oa = builtin_anewarray(count, class_java_lang_reflect_Field);
+       if (oa == NULL)
+               return NULL;
+       /* Get the fields and store them in the array. */
+       for (i = 0, index = 0; i < c->fieldscount; i++) {
+               f = &(c->fields[i]);
+               if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
+                       // Create a java.lang.reflect.Field object.
+                       h = java_lang_reflect_Field_create(f);
+                       /* Store object into array. */
+                       array_objectarray_element_set(oa, index, h);
+                       index++;
+               }
+       }
+       return oa;
+ }
+ #endif
+ /* class_get_declaredmethods ***************************************************
+    Return an array of declared methods of the given class.
+    ARGUMENTS:
+        c ............ class to get the methods of
+          publicOnly ... show only public methods
+    RETURN:
+        array of java.lang.reflect.Method
+ *******************************************************************************/
+ #if defined(ENABLE_JAVASE)
+ java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
+ {
+       java_handle_objectarray_t *oa;         /* result: array of Method-objects */
+       methodinfo                *m;     /* the current method to be represented */
+       java_handle_t             *h;
+       int                        count;
+       int                        index;
+       int                        i;
+       /* JOWENN: array classes do not declare methods according to mauve
+          test.  It should be considered, if we should return to my old
+          clone method overriding instead of declaring it as a member
+          function. */
+       if (class_is_array(c))
+               return builtin_anewarray(0, class_java_lang_reflect_Method);
+       /* Determine number of methods. */
+       count = 0;
+       for (i = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
+                       ((m->name != utf_init) && (m->name != utf_clinit)) &&
+                       !(m->flags & ACC_MIRANDA))
+                       count++;
+       }
+       /* Create array of methods. */
+       oa = builtin_anewarray(count, class_java_lang_reflect_Method);
+       if (oa == NULL)
+               return NULL;
+       /* Get the methods and store them in the array. */
+       for (i = 0, index = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) && 
+                       ((m->name != utf_init) && (m->name != utf_clinit)) &&
+                       !(m->flags & ACC_MIRANDA)) {
+                       // Create java.lang.reflect.Method object.
+                       h = java_lang_reflect_Method_create(m);
+                       /* Store object into array. */
+                       array_objectarray_element_set(oa, index, h);
+                       index++;
+               }
+       }
+       return oa;
+ }
+ #endif
+ /* class_get_declaringclass ****************************************************
+    If the class or interface given is a member of another class,
+    return the declaring class.  For array and primitive classes return
+    NULL.
+ *******************************************************************************/
+ classinfo *class_get_declaringclass(classinfo *c)
+ {
+       classref_or_classinfo  cr;
+       classinfo             *dc;
+       /* Get declaring class. */
+       cr = c->declaringclass;
+       if (cr.any == NULL)
+               return NULL;
+       /* Resolve the class if necessary. */
+       if (IS_CLASSREF(cr)) {
+ /*            dc = resolve_classref_eager(cr.ref); */
+               dc = resolve_classref_or_classinfo_eager(cr, true);
+               if (dc == NULL)
+                       return NULL;
+               /* Store the resolved class in the class structure. */
+               cr.cls = dc;
+       }
+       dc = cr.cls;
+       return dc;
+ }
+ /* class_get_enclosingclass ****************************************************
+    Return the enclosing class for the given class.
+ *******************************************************************************/
+ classinfo *class_get_enclosingclass(classinfo *c)
+ {
+       classref_or_classinfo  cr;
+       classinfo             *ec;
+       /* Get enclosing class. */
+       cr = c->enclosingclass;
+       if (cr.any == NULL)
+               return NULL;
+       /* Resolve the class if necessary. */
+       if (IS_CLASSREF(cr)) {
+ /*            ec = resolve_classref_eager(cr.ref); */
+               ec = resolve_classref_or_classinfo_eager(cr, true);
+               if (ec == NULL)
+                       return NULL;
+               /* Store the resolved class in the class structure. */
+               cr.cls = ec;
+       }
+       ec = cr.cls;
+       return ec;
+ }
+ /**
+  * Return the enclosing constructor as java.lang.reflect.Constructor
+  * object for the given class.
+  *
+  * @param c class to return the enclosing constructor for
+  *
+  * @return java.lang.reflect.Constructor object of the enclosing
+  * constructor
+  */
+ #if defined(ENABLE_JAVASE)
+ java_handle_t* class_get_enclosingconstructor(classinfo *c)
+ {
+       methodinfo*    m;
+       java_handle_t* rc;
+       m = class_get_enclosingmethod_raw(c);
+       if (m == NULL)
+               return NULL;
+       /* Check for <init>. */
+       if (m->name != utf_init)
+               return NULL;
+       // Create a java.lang.reflect.Constructor object.
+       rc = java_lang_reflect_Constructor_create(m);
+       return rc;
+ }
+ #endif
+ /* class_get_enclosingmethod ***************************************************
+    Return the enclosing method for the given class.
+    IN:
+        c ... class to return the enclosing method for
+    RETURN:
+        methodinfo of the enclosing method
+ *******************************************************************************/
+ methodinfo *class_get_enclosingmethod_raw(classinfo *c)
+ {
+       constant_nameandtype *cn;
+       classinfo            *ec;
+       methodinfo           *m;
+       /* get enclosing class and method */
+       ec = class_get_enclosingclass(c);
+       cn = c->enclosingmethod;
+       /* check for enclosing class and method */
+       if (ec == NULL)
+               return NULL;
+       if (cn == NULL)
+               return NULL;
+       /* find method in enclosing class */
+       m = class_findmethod(ec, cn->name, cn->descriptor);
+       if (m == NULL) {
+               exceptions_throw_internalerror("Enclosing method doesn't exist");
+               return NULL;
+       }
+       return m;
+ }
+ /**
+  * Return the enclosing method as java.lang.reflect.Method object for
+  * the given class.
+  *
+  * @param c class to return the enclosing method for
+  *
+  * @return java.lang.reflect.Method object of the enclosing method
+  */
+ #if defined(ENABLE_JAVASE)
+ java_handle_t* class_get_enclosingmethod(classinfo *c)
+ {
+       methodinfo*    m;
+       java_handle_t* rm;
+       m = class_get_enclosingmethod_raw(c);
+       if (m == NULL)
+               return NULL;
+       /* check for <init> */
+       if (m->name == utf_init)
+               return NULL;
+       // Create a java.lang.reflect.Method object.
+       rm = java_lang_reflect_Method_create(m);
+       return rm;
+ }
+ #endif
+ /* class_get_interfaces ********************************************************
+    Return an array of interfaces of the given class.
+ *******************************************************************************/
+ java_handle_objectarray_t *class_get_interfaces(classinfo *c)
+ {
+       classinfo                 *ic;
+       java_handle_objectarray_t *oa;
+       u4                         i;
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return NULL;
+       oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
+       if (oa == NULL)
+               return NULL;
+       for (i = 0; i < c->interfacescount; i++) {
+               ic = c->interfaces[i];
+               LLNI_array_direct(oa, i) = (java_object_t *) ic;
+       }
+       return oa;
+ }
+ /* class_get_annotations *******************************************************
+    Get the unparsed declared annotations in a byte array
+    of the given class.
+    IN:
+        c........the class of which the annotations should be returned
+    RETURN VALUE:
+        The unparsed declared annotations in a byte array
+        (or NULL if there aren't any).
+ *******************************************************************************/
+ java_handle_bytearray_t *class_get_annotations(classinfo *c)
+ {
+ #if defined(ENABLE_ANNOTATIONS)
+       java_handle_t *annotations; /* unparsed annotations */
+       LLNI_classinfo_field_get(c, annotations, annotations);
+       return (java_handle_bytearray_t*)annotations;
+ #else
+       return NULL;
+ #endif
+ }
+ /* class_get_modifiers *********************************************************
+    Get the modifier flags of the given class.
+    IN:
+        c....the class of which the modifier flags should be returned
+          ignoreInnerClassesAttrib
+    RETURN VALUE:
+        modifier flags
+ *******************************************************************************/
+ int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
+ {
+       classref_or_classinfo  inner;
+       classref_or_classinfo  outer;
+       utf                   *innername;
+       int                    i;
+       if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
+               /* search for passed class as inner class */
+               for (i = 0; i < c->innerclasscount; i++) {
+                       inner = c->innerclass[i].inner_class;
+                       outer = c->innerclass[i].outer_class;
+                       /* Check if inner is a classref or a real class and get
+                the name of the structure */
+                       innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
+                       /* innerclass is this class */
+                       if (innername == c->name) {
+                               /* has the class actually an outer class? */
+                               if (outer.any)
+                                       /* return flags got from the outer class file */
+                                       return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
+                               else
+                                       return c->flags & ACC_CLASS_REFLECT_MASK;
+                       }
+               }
+       }
+       /* passed class is no inner class or it was not requested */
+       return c->flags & ACC_CLASS_REFLECT_MASK;
+ }
+ /* class_get_signature *********************************************************
+    Return the signature of the given class.  For array and primitive
+    classes return NULL.
+ *******************************************************************************/
+ #if defined(ENABLE_JAVASE)
+ utf *class_get_signature(classinfo *c)
+ {
+       /* For array and primitive classes return NULL. */
+       if (class_is_array(c) || class_is_primitive(c))
+               return NULL;
+       return c->signature;
+ }
+ #endif
+ /* class_printflags ************************************************************
+    Prints flags of a class.
+ *******************************************************************************/
+ #if !defined(NDEBUG)
+ void class_printflags(classinfo *c)
+ {
+       if (c == NULL) {
+               printf("NULL");
+               return;
+       }
+       if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
+       if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
+       if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
+       if (c->flags & ACC_STATIC)       printf(" STATIC");
+       if (c->flags & ACC_FINAL)        printf(" FINAL");
+       if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
+       if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
+       if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
+       if (c->flags & ACC_NATIVE)       printf(" NATIVE");
+       if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
+       if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
+ }
+ #endif
+ /* class_print *****************************************************************
+    Prints classname plus flags.
+ *******************************************************************************/
+ #if !defined(NDEBUG)
+ void class_print(classinfo *c)
+ {
+       if (c == NULL) {
+               printf("NULL");
+               return;
+       }
+       utf_display_printable_ascii(c->name);
+       class_printflags(c);
+ }
+ #endif
+ /* class_classref_print ********************************************************
+    Prints classname plus referer class.
+ *******************************************************************************/
+ #if !defined(NDEBUG)
+ void class_classref_print(constant_classref *cr)
+ {
+       if (cr == NULL) {
+               printf("NULL");
+               return;
+       }
+       utf_display_printable_ascii(cr->name);
+       printf("(ref.by ");
+       if (cr->referer)
+               class_print(cr->referer);
+       else
+               printf("NULL");
+       printf(")");
+ }
+ #endif
+ /* class_println ***************************************************************
+    Prints classname plus flags and new line.
+ *******************************************************************************/
+ #if !defined(NDEBUG)
+ void class_println(classinfo *c)
+ {
+       class_print(c);
+       printf("\n");
+ }
+ #endif
+ /* class_classref_println ******************************************************
+    Prints classname plus referer class and new line.
+ *******************************************************************************/
+ #if !defined(NDEBUG)
+ void class_classref_println(constant_classref *cr)
+ {
+       class_classref_print(cr);
+       printf("\n");
+ }
+ #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.
+ *******************************************************************************/
+ #if !defined(NDEBUG)
+ void class_classref_or_classinfo_println(classref_or_classinfo c)
+ {
+       class_classref_or_classinfo_print(c);
+       printf("\n");
+ }
+ #endif
+ /* class_showconstantpool ******************************************************
+    Dump the constant pool of the given class to stdout.
+ *******************************************************************************/
+ #if !defined(NDEBUG)
+ void class_showconstantpool (classinfo *c) 
+ {
+       u4 i;
+       void* e;
+       printf ("---- dump of constant pool ----\n");
+       for (i=0; i<c->cpcount; i++) {
+               printf ("#%d:  ", (int) i);
+               
+               e = c -> cpinfos [i];
+               if (e) {
+                       
+                       switch (c -> cptags [i]) {
+                       case CONSTANT_Class:
+                               printf ("Classreference -> ");
+                               utf_display_printable_ascii ( ((constant_classref*)e) -> name );
+                               break;
+                       case CONSTANT_Fieldref:
+                               printf ("Fieldref -> ");
+                               field_fieldref_print((constant_FMIref *) e);
+                               break;
+                       case CONSTANT_Methodref:
+                               printf ("Methodref -> ");
+                               method_methodref_print((constant_FMIref *) e);
+                               break;
+                       case CONSTANT_InterfaceMethodref:
+                               printf ("InterfaceMethod -> ");
+                               method_methodref_print((constant_FMIref *) e);
+                               break;
+                       case CONSTANT_String:
+                               printf ("String -> ");
+                               utf_display_printable_ascii (e);
+                               break;
+                       case CONSTANT_Integer:
+                               printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
+                               break;
+                       case CONSTANT_Float:
+                               printf ("Float -> %f", ((constant_float*)e) -> value);
+                               break;
+                       case CONSTANT_Double:
+                               printf ("Double -> %f", ((constant_double*)e) -> value);
+                               break;
+                       case CONSTANT_Long:
+                               {
+                                       u8 v = ((constant_long*)e) -> value;
+ #if U8_AVAILABLE
+                                       printf ("Long -> %ld", (long int) v);
+ #else
+                                       printf ("Long -> HI: %ld, LO: %ld\n", 
+                                                       (long int) v.high, (long int) v.low);
+ #endif 
+                               }
+                               break;
+                       case CONSTANT_NameAndType:
+                               {
+                                       constant_nameandtype *cnt = e;
+                                       printf ("NameAndType: ");
+                                       utf_display_printable_ascii (cnt->name);
+                                       printf (" ");
+                                       utf_display_printable_ascii (cnt->descriptor);
+                               }
+                               break;
+                       case CONSTANT_Utf8:
+                               printf ("Utf8 -> ");
+                               utf_display_printable_ascii (e);
+                               break;
+                       default: 
+                               log_text("Invalid type of ConstantPool-Entry");
+                               assert(0);
+                       }
+               }
+               printf ("\n");
+       }
+ }
+ #endif /* !defined(NDEBUG) */
+ /* class_showmethods ***********************************************************
+    Dump info about the fields and methods of the given class to stdout.
+ *******************************************************************************/
+ #if !defined(NDEBUG)
+ void class_showmethods (classinfo *c)
+ {
+       s4 i;
+       
+       printf("--------- Fields and Methods ----------------\n");
+       printf("Flags: ");
+       class_printflags(c);
+       printf("\n");
+       printf("This: ");
+       utf_display_printable_ascii(c->name);
+       printf("\n");
+       if (c->super) {
+               printf("Super: ");
+               utf_display_printable_ascii(c->super->name);
+               printf ("\n");
+       }
+       printf("Index: %d\n", c->index);
+       
+       printf("Interfaces:\n");        
+       for (i = 0; i < c->interfacescount; i++) {
+               printf("   ");
+               utf_display_printable_ascii(c->interfaces[i]->name);
+               printf (" (%d)\n", c->interfaces[i]->index);
+       }
+       printf("Fields:\n");
+       for (i = 0; i < c->fieldscount; i++)
+               field_println(&(c->fields[i]));
+       printf("Methods:\n");
+       for (i = 0; i < c->methodscount; i++) {
+               methodinfo *m = &(c->methods[i]);
+               if (!(m->flags & ACC_STATIC))
+                       printf("vftblindex: %d   ", m->vftblindex);
+               method_println(m);
+       }
+       printf ("Virtual function table:\n");
+       for (i = 0; i < c->vftbl->vftbllength; i++)
+               printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
+ }
+ #endif /* !defined(NDEBUG) */
+ /*
+  * These are local overrides for various environment variables in Emacs.
+  * Please do not remove this and leave it at the end of the file, where
+  * Emacs will automagically detect them.
+  * ---------------------------------------------------------------------
+  * Local variables:
+  * mode: c
+  * indent-tabs-mode: t
+  * c-basic-offset: 4
+  * tab-width: 4
+  * End:
+  * vim:noexpandtab:sw=4:ts=4:
+  */
diff --cc src/vm/class.h
index 0000000000000000000000000000000000000000,6cbd1d87e1dbf4d6e69ccacf90b64cfab824bdf8..a1434be849b3a4cf698d44c9d83478d375f61030
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,462 +1,464 @@@
 -
+ /* src/vm/class.h - class related functions header
+    Copyright (C) 1996-2005, 2006, 2007, 2008
+    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+    This file is part of CACAO.
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2, or (at
+    your option) any later version.
+    This program is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+    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., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+ */
+ #ifndef _CLASS_H
+ #define _CLASS_H
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ /* forward typedefs ***********************************************************/
+ typedef struct classinfo      classinfo; 
+ typedef struct innerclassinfo innerclassinfo;
+ typedef struct extra_classref extra_classref;
+ #include "config.h"
+ #include <stdint.h>
+ #include "vm/types.h"
+ #include "toolbox/list.h"
+ #if defined(ENABLE_JAVASE)
+ # include "vm/annotation.h"
+ #endif
+ #include "vm/field.h"
+ #include "vm/global.h"
+ #include "vm/linker.h"
+ #include "vm/loader.h"
+ #include "vm/method.h"
+ #include "vm/references.h"
+ #include "vm/string.hpp"
+ #include "vm/utf8.h"
+ /* class state defines ********************************************************/
+ #define CLASS_LOADING         0x0001
+ #define CLASS_LOADED          0x0002
+ #define CLASS_LINKING         0x0004
+ #define CLASS_LINKED          0x0008
+ #define CLASS_INITIALIZING    0x0010
+ #define CLASS_INITIALIZED     0x0020
+ #define CLASS_ERROR           0x0040
+ /* some macros ****************************************************************/
+ #define CLASS_IS_OR_ALMOST_INITIALIZED(c) \
+     (((c)->state & CLASS_INITIALIZING) || ((c)->state & CLASS_INITIALIZED))
+ /* classinfo ******************************************************************/
+ /* We define this dummy structure of java_lang_Class so we can
+    bootstrap cacaoh without needing a java_lang_Class.h file.  Whether
+    the size of the dummy structure is big enough is checked during
+    runtime in vm_create. */
+ typedef struct {
+       java_object_t      header;
+ #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       intptr_t           padding[4];
+ #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       intptr_t           padding[19];
+ #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+       intptr_t           padding[3];
+ #else
+ # error unknown classpath configuration
+ #endif
+ } dummy_java_lang_Class;
+ struct classinfo {                /* class structure                          */
+       dummy_java_lang_Class object;
+       s4          flags;            /* ACC flags                                */
+       utf        *name;             /* class name                               */
+       s4          cpcount;          /* number of entries in constant pool       */
+       u1         *cptags;           /* constant pool tags                       */
+       void*      *cpinfos;          /* pointer to constant pool info structures */
+       s4          classrefcount;    /* number of symbolic class references      */
+       constant_classref *classrefs; /* table of symbolic class references       */
+       extra_classref *extclassrefs; /* additional classrefs                     */
+       s4          parseddescsize;   /* size of the parsed descriptors block     */
+       u1         *parseddescs;      /* parsed descriptors                       */
+       classinfo  *super;            /* super class                              */
+       classinfo  *sub;              /* sub class pointer                        */
+       classinfo  *nextsub;          /* pointer to next class in sub class list  */
+       int32_t     interfacescount;  /* number of interfaces                     */
+       classinfo **interfaces;       /* super interfaces                         */
+       int32_t     fieldscount;      /* number of fields                         */
+       fieldinfo  *fields;           /* field table                              */
+       int32_t     methodscount;     /* number of methods                        */
+       methodinfo *methods;          /* method table                             */
+       s4          state;            /* current class state                      */
+       s4          index;            /* hierarchy depth (classes) or index       */
+                                     /* (interfaces)                             */
+       s4          instancesize;     /* size of an instance of this class        */
+       vftbl_t    *vftbl;            /* pointer to virtual function table        */
+       methodinfo *finalizer;        /* finalizer method                         */
+       u2          innerclasscount;  /* number of inner classes                  */
+       innerclassinfo *innerclass;
+       classref_or_classinfo  declaringclass;
+       classref_or_classinfo  enclosingclass;  /* enclosing class                */
+       constant_nameandtype  *enclosingmethod; /* enclosing method               */
+       utf        *packagename;      /* full name of the package                 */
+       utf        *sourcefile;       /* SourceFile attribute                     */
+ #if defined(ENABLE_JAVASE)
+       utf        *signature;        /* Signature attribute                      */
+ #if defined(ENABLE_ANNOTATIONS)
+       /* All the annotation attributes are NULL (and not a zero length array)   */
+       /* if there is nothing.                                                   */
+       java_object_t *annotations;   /* annotations of this class                */
+       
+       java_object_t *method_annotations; /* array of annotations of the methods */
+       java_object_t *method_parameterannotations; /* array of parameter         */
+                                     /* annotations of the methods               */
+       java_object_t *method_annotationdefaults; /* array of annotation default  */
+                                     /* values of the methods                    */
+       java_object_t *field_annotations; /* array of annotations of the fields   */
+ #endif
+ #endif
+       classloader_t *classloader;       /* NULL for bootstrap classloader         */
+ #if defined(ENABLE_JAVASE)
+ # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       java_object_t      *protectiondomain;
+       java_objectarray_t *signers;
+ # endif
+ #endif
++#if defined(ENABLE_JITCACHE)
++      int         cache_file_fd;
++#endif
+ };
+ /* innerclassinfo *************************************************************/
+ struct innerclassinfo {
+       classref_or_classinfo inner_class; /* inner class pointer                 */
+       classref_or_classinfo outer_class; /* outer class pointer                 */
+       utf                  *name;        /* innerclass name                     */
+       s4                    flags;       /* ACC flags                           */
+ };
+ /* extra_classref **************************************************************
+    for classrefs not occurring within descriptors
+ *******************************************************************************/
+ struct extra_classref {
+       extra_classref    *next;
+       constant_classref  classref;
+ };
+ /* inline functions ***********************************************************/
+ /**
+  * Returns the classname of the class, where slashes ('/') are
+  * replaced by dots ('.').
+  *
+  * @param c class to get name of
+  * @return classname
+  */
+ inline static java_handle_t* class_get_classname(classinfo* c)
+ {
+       java_handle_t *s;
+       /* Create a java string. */
+       s = javastring_new_slash_to_dot(c->name);
+       return s;
+ }
+ /* class_is_primitive **********************************************************
+    Checks if the given class is a primitive class.
+ *******************************************************************************/
+ static inline bool class_is_primitive(classinfo *c)
+ {
+       if (c->flags & ACC_CLASS_PRIMITIVE)
+               return true;
+       return false;
+ }
+ /* class_is_anonymousclass *****************************************************
+    Checks if the given class is an anonymous class.
+ *******************************************************************************/
+ static inline bool class_is_anonymousclass(classinfo *c)
+ {
+       if (c->flags & ACC_CLASS_ANONYMOUS)
+               return true;
+       return false;
+ }
+ /* class_is_array **************************************************************
+    Checks if the given class is an array class.
+ *******************************************************************************/
+ static inline bool class_is_array(classinfo *c)
+ {
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return false;
+       return (c->vftbl->arraydesc != NULL);
+ }
+ /* class_is_interface **********************************************************
+    Checks if the given class is an interface.
+ *******************************************************************************/
+ static inline bool class_is_interface(classinfo *c)
+ {
+       if (c->flags & ACC_INTERFACE)
+               return true;
+       return false;
+ }
+ /* class_is_localclass *********************************************************
+    Checks if the given class is a local class.
+ *******************************************************************************/
+ static inline bool class_is_localclass(classinfo *c)
+ {
+       if ((c->enclosingmethod != NULL) && !class_is_anonymousclass(c))
+               return true;
+       return false;
+ }
+ /* class_is_memberclass ********************************************************
+    Checks if the given class is a member class.
+ *******************************************************************************/
+ static inline bool class_is_memberclass(classinfo *c)
+ {
+       if (c->flags & ACC_CLASS_MEMBER)
+               return true;
+       return false;
+ }
+ /* class_get_classloader *******************************************************
+    Return the classloader of the given class.
+ *******************************************************************************/
+ static inline classloader_t *class_get_classloader(classinfo *c)
+ {
+       classloader_t *cl;
+       cl = c->classloader;
+       /* The classloader may be NULL. */
+       return cl;
+ }
+ /* class_get_superclass ********************************************************
+    Return the super class of the given class.
+ *******************************************************************************/
+ static inline classinfo *class_get_superclass(classinfo *c)
+ {
+       /* For interfaces we return NULL. */
+       if (c->flags & ACC_INTERFACE)
+               return NULL;
+       /* For java/lang/Object, primitive-type and Void classes c->super
+          is NULL and we return NULL. */
+       return c->super;
+ }
+ /* function prototypes ********************************************************/
+ classinfo *class_create_classinfo(utf *u);
+ void       class_postset_header_vftbl(void);
+ classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd);
+ void       class_set_packagename(classinfo *c);
+ bool       class_load_attributes(classbuffer *cb);
+ /* retrieve constantpool element */
+ void* class_getconstant(classinfo *c, u4 pos, u4 ctype);
+ void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype);
+ /* 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,bool link);
+ /* return an array class with the given dimension and element class */
+ classinfo *class_multiarray_of(s4 dim, classinfo *element,bool link);
+ /* return a classref for the given class name */
+ /* (does a linear search!)                    */
+ constant_classref *class_lookup_classref(classinfo *cls,utf *name);
+ /* return a classref for the given class name */
+ /* (does a linear search!)                    */
+ constant_classref *class_get_classref(classinfo *cls,utf *name);
+ /* return a classref to the class itself */
+ /* (does a linear search!)                    */
+ constant_classref *class_get_self_classref(classinfo *cls);
+ /* return a classref for an array with the given dimension of with the */
+ /* given component type */
+ constant_classref *class_get_classref_multiarray_of(s4 dim,constant_classref *ref);
+ /* return a classref for the component type of the given array type */
+ constant_classref *class_get_classref_component_of(constant_classref *ref);
+ /* get a class' field by name and descriptor */
+ fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc);
+ /* search 'classinfo'-structure for a field with the specified name */
+ fieldinfo *class_findfield_by_name(classinfo *c, utf *name);
+ /* search class for a field */
+ fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer);
+ /* search for a method with a specified name and descriptor */
+ methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc);
+ methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *dest);
+ methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
+ methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
+ bool                       class_issubclass(classinfo *sub, classinfo *super);
+ bool                       class_isanysubclass(classinfo *sub, classinfo *super);
+ bool                       class_is_assignable_from(classinfo *to, classinfo *from);
+ bool                       class_is_instance(classinfo *c, java_handle_t *h);
+ classloader_t             *class_get_classloader(classinfo *c);
+ classinfo                 *class_get_superclass(classinfo *c);
+ classinfo                 *class_get_componenttype(classinfo *c);
+ java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly);
+ java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly);
+ java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly);
+ java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly);
+ classinfo                 *class_get_declaringclass(classinfo *c);
+ classinfo                 *class_get_enclosingclass(classinfo *c);
+ java_handle_t*             class_get_enclosingconstructor(classinfo *c);
+ methodinfo*                class_get_enclosingmethod_raw(classinfo *c);
+ java_handle_t*             class_get_enclosingmethod(classinfo *c);
+ java_handle_objectarray_t *class_get_interfaces(classinfo *c);
+ java_handle_bytearray_t   *class_get_annotations(classinfo *c);
+ int32_t                    class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib);
+ java_handle_t             *class_get_name(classinfo *c);
+ #if defined(ENABLE_JAVASE)
+ utf                       *class_get_signature(classinfo *c);
+ #endif
+ /* some debugging functions */
+ #if !defined(NDEBUG)
+ void class_printflags(classinfo *c);
+ void class_print(classinfo *c);
+ void class_println(classinfo *c);
+ void class_classref_print(constant_classref *cr);
+ void class_classref_println(constant_classref *cr);
+ void class_classref_or_classinfo_print(classref_or_classinfo c);
+ void class_classref_or_classinfo_println(classref_or_classinfo c);
+ #endif
+ /* debug purposes */
+ void class_showmethods(classinfo *c);
+ void class_showconstantpool(classinfo *c);
+ #ifdef __cplusplus
+ }
+ #endif
+ #endif /* _CLASS_H */
+ /*
+  * These are local overrides for various environment variables in Emacs.
+  * Please do not remove this and leave it at the end of the file, where
+  * Emacs will automagically detect them.
+  * ---------------------------------------------------------------------
+  * Local variables:
+  * mode: c
+  * indent-tabs-mode: t
+  * c-basic-offset: 4
+  * tab-width: 4
+  * End:
+  */
Simple merge
Simple merge
Simple merge
index 0a7e70cc589b0f975f1821a26f64c0762595d8a5,02c3a2d2fa594a39776796e745104a8de99f1a6d..750de64137fc373abecddf8bc996c03c0640b0e5
  
  #include "vm/jit/code.h"
  #include "vm/jit/codegen-common.h"
 -#include "vm/jit/patcher-common.h"
 +#include "vm/jit/jitcache.h"
  #include "vm/jit/methodtree.h"
 +#include "vm/jit/patcher-common.h"
  
- #include "vmcore/options.h"
  
  /* code_init *******************************************************************
  
Simple merge
Simple merge
index 6c08b9cfb756126d328766c526eda5546a7468ee,d18b645e8a57460f702b4e0fc5af9e3496d7cf23..12ebffd59ea0062709fefa5ed5698022948a1753
@@@ -56,6 -58,6 +58,7 @@@
  #include "vm/jit/dseg.h"
  #include "vm/jit/emit-common.h"
  #include "vm/jit/jit.h"
++#include "vm/jit/jitcache.h"
  #include "vm/jit/linenumbertable.h"
  #include "vm/jit/parse.h"
  #include "vm/jit/patcher-common.h"
@@@ -3157,10 -3114,7 +3167,6 @@@ gen_method
                                        superindex = super->index;
                                        supervftbl = super->vftbl;
                                }
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                                       CODEGEN_CRITICAL_SECTION_NEW;
 -                      
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
  
                                /* if class is not resolved, check which code to call */
                                        }
  
                                        M_MOV_IMM(supervftbl, REG_ITMP3);
 +                                      JITCACHE_ADD_CACHED_REF_JD(jd, CRT_CLASSINFO_VFTBL, super);
  
-                                       CODEGEN_CRITICAL_SECTION_START;
                                        M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
  
                                        /*                              if (s1 != REG_ITMP1) { */
                                        M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
                                        M_ISUB(REG_ITMP3, REG_ITMP2);
                                        M_MOV_IMM(supervftbl, REG_ITMP3);
 +                                      JITCACHE_ADD_CACHED_REF_JD(jd, CRT_CLASSINFO_VFTBL, super);
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
  
-                                       CODEGEN_CRITICAL_SECTION_END;
                                        /*                              } */
  
                                        M_CMP(REG_ITMP3, REG_ITMP2);
                                }
  
                                M_MOV_IMM(supervftbl, REG_ITMP2);
 -
 +                              JITCACHE_ADD_CACHED_REF_JD(jd, CRT_CLASSINFO_VFTBL, super);
-                               CODEGEN_CRITICAL_SECTION_START;
                                M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
Simple merge
index 4225c66c66da01876cf354b5915ddb11b26d2dbb,e703bda80dcbd1efaf2c6380edea18fc6433c04f..cf2cf5b34d6dbeb587a26a6d539af04860df5494
  #include "vm/jit/show.h"
  #include "vm/jit/stack.h"
  
 +#if defined(ENABLE_JITCACHE)
 +# include "vm/jit/jitcache.h"
 +#endif
 +
+ #if defined(ENABLE_OPAGENT)
+ #include "vm/jit/oprofile-agent.hpp"
+ #endif
  #include "vm/jit/allocator/simplereg.h"
  #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
  # include "vm/jit/allocator/lsra.h"
Simple merge
index f4cf9a50745fa90ea1fba843596488f836d1ee15,7328b5ed897354c037b8e342a8f32251d3a6be3d..994599a7826706d082cb6d168170350b4492492f
@@@ -55,14 -50,9 +53,14 @@@ typedef struct patchref_t 
        ptrint       datap;         /* absolute position in data segment          */
        s4           disp;          /* displacement of ref in the data segment    */
        functionptr  patcher;       /* patcher function to call                   */
-       voidptr      ref;           /* reference passed                           */
+       void*        ref;           /* reference passed                           */
        u8           mcode;         /* machine code to be patched back in         */
        bool         done;          /* XXX preliminary: patch already applied?    */
 +#if defined (ENABLE_JITCACHE)
 +      struct cachedref_t *attached_ref;
 +                                                              /* cached reference which must be resolved    *
 +                                                               * patcher has been run.                      */
 +#endif
        listnode_t   linkage;
  } patchref_t;
  
index 0000000000000000000000000000000000000000,42adb3f909c86005de44022c4b3444fe839f1bd5..0366ebefe7cf2f54177b8a24f47aa611888af726
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,853 +1,866 @@@
+ /* src/vm/options.c - contains global options
+    Copyright (C) 1996-2005, 2006, 2007, 2008
+    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+    This file is part of CACAO.
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2, or (at
+    your option) any later version.
+    This program is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+    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., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+ */
+ #include "config.h"
+ #include <limits.h>
+ #include <stdint.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include "mm/memory.h"
+ #include "native/jni.h"
+ #include "vm/options.h"
+ #include "vm/os.hpp"
+ #include "vm/vm.hpp"
+ /* command line option ********************************************************/
+ s4    opt_index = 0;            /* index of processed arguments               */
+ char *opt_arg;                  /* this one exports the option argument       */
+ bool opt_foo = false;           /* option for development                     */
+ bool opt_jar = false;
+ #if defined(ENABLE_JIT)
+ bool opt_jit = true;            /* JIT mode execution (default)               */
+ bool opt_intrp = false;         /* interpreter mode execution                 */
+ #else
+ bool opt_jit = false;           /* JIT mode execution                         */
+ bool opt_intrp = true;          /* interpreter mode execution (default)       */
+ #endif
+ bool opt_run = true;
+ s4   opt_heapmaxsize   = 0;     /* maximum heap size                          */
+ s4   opt_heapstartsize = 0;     /* initial heap size                          */
+ s4   opt_stacksize     = 0;     /* thread stack size                          */
+ bool opt_verbose = false;
+ bool opt_debugcolor = false;  /* use ANSI terminal sequences                */
+ bool compileall = false;
+ bool loadverbose = false;
+ bool initverbose = false;
+ bool opt_verboseclass     = false;
+ bool opt_verbosegc        = false;
+ bool opt_verbosejni       = false;
+ bool opt_verbosecall      = false;      /* trace all method invocation        */
+ bool showmethods = false;
+ bool showconstantpool = false;
+ bool showutf = false;
+ char *opt_method = NULL;
+ char *opt_signature = NULL;
+ bool compileverbose =  false;           /* trace compiler actions             */
+ bool showstack = false;
+ bool opt_showdisassemble    = false;    /* generate disassembler listing      */
+ bool opt_shownops           = false;
+ bool opt_showddatasegment   = false;    /* generate data segment listing      */
+ bool opt_showintermediate   = false;    /* generate intermediate code listing */
+ bool checkbounds = true;       /* check array bounds                         */
+ bool opt_noieee = false;       /* don't implement ieee compliant floats      */
+ bool checksync = true;         /* do synchronization                         */
+ #if defined(ENABLE_LOOP)
+ bool opt_loops = false;        /* optimize array accesses in loops           */
+ #endif
+ bool makeinitializations = true;
+ #if defined(ENABLE_STATISTICS)
+ bool opt_stat    = false;
+ bool opt_getloadingtime = false;   /* to measure the runtime                 */
+ bool opt_getcompilingtime = false; /* compute compile time                   */
+ #endif
+ #if defined(ENABLE_VERIFIER)
+ bool opt_verify  = true;       /* true if classfiles should be verified      */
+ #endif
+ #if defined(ENABLE_PROFILING)
+ bool opt_prof    = false;
+ bool opt_prof_bb = false;
+ #endif
+ #if defined(ENABLE_OPAGENT)
+ bool opt_opagent = false;
+ #endif
+ /* optimization options *******************************************************/
+ #if defined(ENABLE_IFCONV)
+ bool opt_ifconv = false;
+ #endif
+ #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+ bool opt_lsra = false;
+ #endif
+ #if defined(ENABLE_SSA)
+ bool opt_ssa_dce = false;          /* enable dead code elemination */
+ bool opt_ssa_cp = false;           /* enable copy propagation      */
+ #endif
+ /* interpreter options ********************************************************/
+ #if defined(ENABLE_INTRP)
+ bool opt_no_dynamic = false;            /* suppress dynamic superinstructions */
+ bool opt_no_replication = false;        /* don't use replication in intrp     */
+ bool opt_no_quicksuper = false;         /* instructions for quickening cannot be
+                                                                                  part of dynamic superinstructions */
+ s4   opt_static_supers = 0x7fffffff;
+ bool vm_debug = false;          /* XXX this should be called `opt_trace'      */
+ #endif
+ #if defined(ENABLE_DEBUG_FILTER)
+ const char *opt_filter_verbosecall_include = 0;
+ const char *opt_filter_verbosecall_exclude = 0;
+ const char *opt_filter_show_method = 0;
+ #endif
+ /* -XX options ****************************************************************/
+ /* NOTE: For better readability keep these alpha-sorted. */
+ /* Options which must always be available (production options in
+    HotSpot). */
+ int64_t  opt_MaxDirectMemorySize          = -1;
+ int      opt_MaxPermSize                  = 0;
+ int      opt_PermSize                     = 0;
+ int      opt_ThreadStackSize              = 0;
+ /* Debugging options which can be turned off. */
+ int      opt_DebugExceptions              = 0;
+ int      opt_DebugFinalizer               = 0;
++#if defined(ENABLE_JITCACHE)
++int      opt_DebugJitCache                = 0;
++#endif
+ int      opt_DebugLocalReferences         = 0;
+ int      opt_DebugLocks                   = 0;
+ int      opt_DebugPackage                 = 0;
+ int      opt_DebugPatcher                 = 0;
+ int      opt_DebugProperties              = 0;
+ int      opt_DebugStackFrameInfo          = 0;
+ int      opt_DebugStackTrace              = 0;
+ int      opt_DebugThreads                 = 0;
+ #if defined(ENABLE_DISASSEMBLER)
+ int      opt_DisassembleStubs             = 0;
+ #endif
+ #if defined(ENABLE_OPAGENT)
+ int      opt_EnableOpagent                = 0;
+ #endif
+ #if defined(ENABLE_GC_CACAO)
+ int      opt_GCDebugRootSet               = 0;
+ int      opt_GCStress                     = 0;
+ #endif
+ #if defined(ENABLE_INLINING)
+ int      opt_Inline                       = 0;
+ #if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
+ int      opt_InlineAll                    = 0;
+ int      opt_InlineCount                  = INT_MAX;
+ int      opt_InlineMaxSize                = INT_MAX;
+ int      opt_InlineMinSize                = 0;
+ #endif
+ #endif
+ int      opt_PrintConfig                  = 0;
+ int      opt_ProfileGCMemoryUsage         = 0;
+ int      opt_ProfileMemoryUsage           = 0;
+ FILE    *opt_ProfileMemoryUsageGNUPlot    = NULL;
+ #if defined(ENABLE_REPLACEMENT)
+ int      opt_TestReplacement              = 0;
+ #endif
+ int      opt_TraceCompilerCalls           = 0;
+ int      opt_TraceExceptions              = 0;
+ int      opt_TraceHPI                     = 0;
+ #if defined(ENABLE_INLINING) && !defined(NDEBUG)
+ int      opt_TraceInlining                = 0;
+ #endif
+ int      opt_TraceJavaCalls               = 0;
+ int      opt_TraceJNICalls                = 0;
+ int      opt_TraceJVMCalls                = 0;
+ int      opt_TraceJVMCallsVerbose         = 0;
+ int      opt_TraceLinkClass               = 0;
+ #if defined(ENABLE_REPLACEMENT)
+ int      opt_TraceReplacement             = 0;
+ #endif
+ int      opt_TraceSubsystemInitialization = 0;
+ int      opt_TraceTraps                   = 0;
+ enum {
+       OPT_TYPE_BOOLEAN,
+       OPT_TYPE_VALUE
+ };
+ enum {
+       /* Options which must always be available (production options in
+          HotSpot). */
+       OPT_MaxDirectMemorySize,
+       OPT_MaxPermSize,
+       OPT_PermSize,
+       OPT_ThreadStackSize,
+       /* Debugging options which can be turned off. */
+       OPT_DebugExceptions,
+       OPT_DebugFinalizer,
++  OPT_DebugJitCache,
+       OPT_DebugLocalReferences,
+       OPT_DebugLocks,
+       OPT_DebugPackage,
+       OPT_DebugPatcher,
+       OPT_DebugProperties,
+       OPT_DebugStackFrameInfo,
+       OPT_DebugStackTrace,
+       OPT_DebugThreads,
+       OPT_DisassembleStubs,
+       OPT_EnableOpagent,
+       OPT_GCDebugRootSet,
+       OPT_GCStress,
+       OPT_Inline,
+       OPT_InlineAll,
+       OPT_InlineCount,
+       OPT_InlineMaxSize,
+       OPT_InlineMinSize,
+       OPT_PrintConfig,
+       OPT_ProfileGCMemoryUsage,
+       OPT_ProfileMemoryUsage,
+       OPT_ProfileMemoryUsageGNUPlot,
+       OPT_TestReplacement,
+       OPT_TraceCompilerCalls,
+       OPT_TraceExceptions,
+       OPT_TraceHPI,
+       OPT_TraceInlining,
+       OPT_TraceJavaCalls,
+       OPT_TraceJNICalls,
+       OPT_TraceJVMCalls,
+       OPT_TraceJVMCallsVerbose,
+       OPT_TraceLinkClass,
+       OPT_TraceReplacement,
+       OPT_TraceSubsystemInitialization,
+       OPT_TraceTraps,
+       OPT_Vmlog,
+       OPT_VmlogStrings,
+       OPT_VmlogIgnore
+ };
+ option_t options_XX[] = {
+       /* Options which must always be available (production options in
+          HotSpot). */
+       { "MaxDirectMemorySize",          OPT_MaxDirectMemorySize,          OPT_TYPE_VALUE,   "Maximum total size of NIO direct-buffer allocations" },
+       { "MaxPermSize",                  OPT_MaxPermSize,                  OPT_TYPE_VALUE,   "not implemented" },
+       { "PermSize",                     OPT_PermSize,                     OPT_TYPE_VALUE,   "not implemented" },
+       { "ThreadStackSize",              OPT_ThreadStackSize,              OPT_TYPE_VALUE,   "TODO" },
+       /* Debugging options which can be turned off. */
+       { "DebugExceptions",              OPT_DebugExceptions,              OPT_TYPE_BOOLEAN, "debug exceptions" },
+       { "DebugFinalizer",               OPT_DebugFinalizer,               OPT_TYPE_BOOLEAN, "debug finalizer thread" },
++#if defined (ENABLE_JITCACHE)
++  { "DebugJitCache",                OPT_DebugJitCache,                OPT_TYPE_BOOLEAN, "debug JIT cache actions" },
++#endif
+       { "DebugLocalReferences",         OPT_DebugLocalReferences,         OPT_TYPE_BOOLEAN, "print debug information for local reference tables" },
+       { "DebugLocks",                   OPT_DebugLocks,                   OPT_TYPE_BOOLEAN, "print debug information for locks" },
+       { "DebugPackage",                 OPT_DebugPackage,                 OPT_TYPE_BOOLEAN, "debug Java boot-packages" },
+       { "DebugPatcher",                 OPT_DebugPatcher,                 OPT_TYPE_BOOLEAN, "debug JIT code patching" },
+       { "DebugProperties",              OPT_DebugProperties,              OPT_TYPE_BOOLEAN, "print debug information for properties" },
+       { "DebugStackFrameInfo",          OPT_DebugStackFrameInfo,          OPT_TYPE_BOOLEAN, "TODO" },
+       { "DebugStackTrace",              OPT_DebugStackTrace,              OPT_TYPE_BOOLEAN, "debug stacktrace creation" },
+       { "DebugThreads",                 OPT_DebugThreads,                 OPT_TYPE_BOOLEAN, "print debug information for threads" },
+ #if defined(ENABLE_DISASSEMBLER)
+       { "DisassembleStubs",             OPT_DisassembleStubs,             OPT_TYPE_BOOLEAN, "disassemble builtin and native stubs when generated" },
+ #endif
+ #if defined(ENABLE_OPAGENT)
+       { "EnableOpagent",                OPT_EnableOpagent,                OPT_TYPE_BOOLEAN, "enable providing JIT output to Oprofile" },
+ #endif
+ #if defined(ENABLE_GC_CACAO)
+       { "GCDebugRootSet",               OPT_GCDebugRootSet,               OPT_TYPE_BOOLEAN, "GC: print root-set at collection" },
+       { "GCStress",                     OPT_GCStress,                     OPT_TYPE_BOOLEAN, "GC: forced collection at every allocation" },
+ #endif
+ #if defined(ENABLE_INLINING)
+       { "Inline",                       OPT_Inline,                       OPT_TYPE_BOOLEAN, "enable method inlining" },
+ #if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
+       { "InlineAll",                    OPT_InlineAll,                    OPT_TYPE_BOOLEAN, "use inlining in all compilations" },
+       { "InlineCount",                  OPT_InlineCount,                  OPT_TYPE_VALUE,   "stop inlining after the given number of roots" },
+       { "InlineMaxSize",                OPT_InlineMaxSize,                OPT_TYPE_VALUE,   "maximum size for inlined result" },
+       { "InlineMinSize",                OPT_InlineMinSize,                OPT_TYPE_VALUE,   "minimum size for inlined result" },
+ #endif
+ #endif
+       { "PrintConfig",                  OPT_PrintConfig,                  OPT_TYPE_BOOLEAN, "print VM configuration" },
+       { "ProfileGCMemoryUsage",         OPT_ProfileGCMemoryUsage,         OPT_TYPE_VALUE,   "profiles GC memory usage in the given interval, <value> is in seconds (default: 5)" },
+       { "ProfileMemoryUsage",           OPT_ProfileMemoryUsage,           OPT_TYPE_VALUE,   "TODO" },
+       { "ProfileMemoryUsageGNUPlot",    OPT_ProfileMemoryUsageGNUPlot,    OPT_TYPE_VALUE,   "TODO" },
+ #if defined(ENABLE_REPLACEMENT)
+       { "TestReplacement",              OPT_TestReplacement,              OPT_TYPE_BOOLEAN, "activate all replacement points during code generation" },
+ #endif
+       { "TraceCompilerCalls",           OPT_TraceCompilerCalls,           OPT_TYPE_BOOLEAN, "trace JIT compiler calls" },
+       { "TraceExceptions",              OPT_TraceExceptions,              OPT_TYPE_BOOLEAN, "trace Exception throwing" },
+       { "TraceHPI",                     OPT_TraceHPI,                     OPT_TYPE_BOOLEAN, "Trace Host Porting Interface (HPI)" },
+ #if defined(ENABLE_INLINING) && !defined(NDEBUG)
+       { "TraceInlining",                OPT_TraceInlining,                OPT_TYPE_VALUE,   "trace method inlining with the given verbosity level (default: 1)" },
+ #endif
+ #if !defined(ENABLE_VMLOG)
+       { "TraceJavaCalls",               OPT_TraceJavaCalls,               OPT_TYPE_BOOLEAN, "trace Java method calls" },
+ #endif
+       { "TraceJNICalls",                OPT_TraceJNICalls,                OPT_TYPE_BOOLEAN, "trace JNI method calls" },
+       { "TraceJVMCalls",                OPT_TraceJVMCalls,                OPT_TYPE_BOOLEAN, "trace JVM method calls but omit very frequent ones" },
+       { "TraceJVMCallsVerbose",         OPT_TraceJVMCallsVerbose,         OPT_TYPE_BOOLEAN, "trace all JVM method calls" },
+       { "TraceLinkClass",               OPT_TraceLinkClass,               OPT_TYPE_BOOLEAN, "trace class linking" },
+ #if defined(ENABLE_REPLACEMENT)
+       { "TraceReplacement",             OPT_TraceReplacement,             OPT_TYPE_VALUE,   "trace on-stack replacement with the given verbosity level (default: 1)" },
+ #endif
+       { "TraceSubsystemInitialization", OPT_TraceSubsystemInitialization, OPT_TYPE_BOOLEAN, "trace initialization of subsystems" },
+       { "TraceTraps",                   OPT_TraceTraps,                   OPT_TYPE_BOOLEAN, "trace traps generated by JIT code" },
+ #if defined(ENABLE_VMLOG)
+       { "Vmlog",                        OPT_Vmlog,                        OPT_TYPE_VALUE,   "prefix for vmlog trace files (enables vmlog)" },
+       { "VmlogStrings",                 OPT_VmlogStrings,                 OPT_TYPE_VALUE,   "prefix of vmlog string file to load" },
+       { "VmlogIgnore",                  OPT_VmlogIgnore,                  OPT_TYPE_VALUE,   "prefix of vmlog ignore file to load" },
+ #endif
+       /* end marker */
+       { NULL,                           -1,                               -1,               NULL }
+ };
+ /* options_get *****************************************************************
+    DOCUMENT ME!!!
+ *******************************************************************************/
+ int options_get(opt_struct *opts, JavaVMInitArgs *vm_args)
+ {
+       char *option;
+       int   i;
+       if (opt_index >= vm_args->nOptions)
+               return OPT_DONE;
+       /* get the current option */
+       option = vm_args->options[opt_index].optionString;
+       if ((option == NULL) || (option[0] != '-'))
+               return OPT_DONE;
+       for (i = 0; opts[i].name; i++) {
+               if (!opts[i].arg) {
+                       /* boolean option found */
+                       if (strcmp(option + 1, opts[i].name) == 0) {
+                               opt_index++;
+                               return opts[i].value;
+                       }
+               } else {
+                       /* parameter option found */
+                       /* with a space between */
+                       if (strcmp(option + 1, opts[i].name) == 0) {
+                               opt_index++;
+                               if (opt_index < vm_args->nOptions) {
+                                       opt_arg = os_strdup(vm_args->options[opt_index].optionString);
+                                       opt_index++;
+                                       return opts[i].value;
+                               }
+                               return OPT_ERROR;
+                       } else {
+                               /* parameter and option have no space between */
+                               /* FIXME: this assumption is plain wrong, hits you if there is a
+                                * parameter with no argument starting with same letter as param with argument
+                                * but named after that one, ouch! */
+                               size_t l = os_strlen(opts[i].name);
+                               if (os_strlen(option + 1) > l) {
+                                       if (memcmp(option + 1, opts[i].name, l) == 0) {
+                                               opt_index++;
+                                               opt_arg = os_strdup(option + 1 + l);
+                                               return opts[i].value;
+                                       }
+                               }
+                       }
+               }
+       }
+       return OPT_ERROR;
+ }
+ /* options_xxusage *************************************************************
+    Print usage message for debugging options.
+ *******************************************************************************/
+ static void options_xxusage(void)
+ {
+       option_t   *opt;
+       int         length;
+       int         i;
+       const char *c;
+       /* Prevent compiler warning. */
+       length = 0;
+       for (opt = options_XX; opt->name != NULL; opt++) {
+               printf("    -XX:");
+               switch (opt->type) {
+               case OPT_TYPE_BOOLEAN:
+                       printf("+%s", opt->name);
+                       length = os_strlen("    -XX:+") + os_strlen(opt->name);
+                       break;
+               case OPT_TYPE_VALUE:
+                       printf("%s=<value>", opt->name);
+                       length = os_strlen("    -XX:") + os_strlen(opt->name) +
+                               os_strlen("=<value>");
+                       break;
+               default:
+                       vm_abort("options_xxusage: unkown option type %d", opt->type);
+               }
+               /* Check if the help fits into one 80-column line.
+                  Documentation starts at column 29. */
+               if (length < (29 - 1)) {
+                       /* Print missing spaces up to column 29. */
+                       for (i = length; i < 29; i++)
+                               printf(" ");
+               }
+               else {
+                       printf("\n");
+                       printf("                             "); /* 29 spaces */
+               }
+               /* Check documentation length. */
+               length = os_strlen(opt->doc);
+               if (length < (80 - 29)) {
+                       printf("%s", opt->doc);
+               }
+               else {
+                       for (c = opt->doc, i = 29; *c != 0; c++, i++) {
+                               /* If we are at the end of the line, break it. */
+                               if (i == 80) {
+                                       printf("\n");
+                                       printf("                             "); /* 29 spaces */
+                                       i = 29;
+                               }
+                               printf("%c", *c);
+                       }
+               }
+               printf("\n");
+       }
+       /* exit with error code */
+       exit(1);
+ }
+ /* options_xx ******************************************************************
+    Handle -XX: options.
+ *******************************************************************************/
+ void options_xx(JavaVMInitArgs *vm_args)
+ {
+       const char *name;
+       const char *start;
+       char       *end;
+       int         length;
+       int         enable;
+       char       *value;
+       option_t   *opt;
+       char       *filename;
+       FILE       *file;
+       int         i;
+       /* Iterate over all passed options. */
+       for (i = 0; i < vm_args->nOptions; i++) {
+               /* Get the current option. */
+               name = vm_args->options[i].optionString;
+               /* Check for help (-XX). */
+               if (strcmp(name, "-XX") == 0)
+                       options_xxusage();
+               /* Check if the option start with -XX. */
+               start = strstr(name, "-XX:");
+               if ((start == NULL) || (start != name))
+                       continue;
+               /* Check if the option is a boolean option. */
+               if (name[4] == '+') {
+                       start  = name + 4 + 1;
+                       enable = 1;
+               }
+               else if (name[4] == '-') {
+                       start  = name + 4 + 1;
+                       enable = 0;
+               }
+               else {
+                       start  = name + 4;
+                       enable = -1;
+               }
+               /* Search for a '=' in the option name and get the option name
+                  length and the value of the option. */
+               end = strchr(start, '=');
+               if (end == NULL) {
+                       length = os_strlen(start);
+                       value  = NULL;
+               }
+               else {
+                       length = end - start;
+                       value  = end + 1;
+               }
+               /* Search the option in the option array. */
+               for (opt = options_XX; opt->name != NULL; opt++) {
+                       if (strncmp(opt->name, start, length) == 0) {
+                               /* Check if the options passed fits to the type. */
+                               switch (opt->type) {
+                               case OPT_TYPE_BOOLEAN:
+                                       if ((enable == -1) || (value != NULL))
+                                               options_xxusage();
+                                       break;
+                               case OPT_TYPE_VALUE:
+                                       if ((enable != -1) || (value == NULL))
+                                               options_xxusage();
+                                       break;
+                               default:
+                                       vm_abort("options_xx: unknown option type %d for option %s",
+                                                        opt->type, opt->name);
+                               }
+                               break;
+                       }
+               }
+               /* Process the option. */
+               switch (opt->value) {
+               /* Options which must always be available (production options
+                  in HotSpot). */
+               case OPT_MaxDirectMemorySize:
+                       opt_MaxDirectMemorySize = os_atoi(value);
+                       break;
+               case OPT_MaxPermSize:
+                       /* Currently ignored. */
+                       break;
+               case OPT_PermSize:
+                       /* Currently ignored. */
+                       break;
+               case OPT_ThreadStackSize:
+                       /* currently ignored */
+                       break;
+               /* Debugging options which can be turned off. */
+               case OPT_DebugExceptions:
+                       opt_DebugExceptions = enable;
+                       break;
+               case OPT_DebugFinalizer:
+                       opt_DebugFinalizer = enable;
+                       break;
++#if defined(ENABLE_JITCACHE)
++    case OPT_DebugJitCache:
++      opt_DebugJitCache = enable;
++      break;
++#endif
++
+               case OPT_DebugLocalReferences:
+                       opt_DebugLocalReferences = enable;
+                       break;
+               case OPT_DebugLocks:
+                       opt_DebugLocks = enable;
+                       break;
+               case OPT_DebugPackage:
+                       opt_DebugPackage = enable;
+                       break;
+               case OPT_DebugPatcher:
+                       opt_DebugPatcher = enable;
+                       break;
+               case OPT_DebugProperties:
+                       opt_DebugProperties = enable;
+                       break;
+               case OPT_DebugStackFrameInfo:
+                       opt_DebugStackFrameInfo = enable;
+                       break;
+               case OPT_DebugStackTrace:
+                       opt_DebugStackTrace = enable;
+                       break;
+               case OPT_DebugThreads:
+                       opt_DebugThreads = enable;
+                       break;
+ #if defined(ENABLE_DISASSEMBLER)
+               case OPT_DisassembleStubs:
+                       opt_DisassembleStubs = enable;
+                       break;
+ #endif
+ #if defined(ENABLE_OPAGENT)
+               case OPT_EnableOpagent:
+                       opt_EnableOpagent = enable;
+                       break;
+ #endif
+ #if defined(ENABLE_GC_CACAO)
+               case OPT_GCDebugRootSet:
+                       opt_GCDebugRootSet = enable;
+                       break;
+               case OPT_GCStress:
+                       opt_GCStress = enable;
+                       break;
+ #endif
+ #if defined(ENABLE_INLINING)
+               case OPT_Inline:
+                       opt_Inline = enable;
+                       break;
+ #if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
+               case OPT_InlineAll:
+                       opt_InlineAll = enable;
+                       break;
+               case OPT_InlineCount:
+                       if (value != NULL)
+                               opt_InlineCount = os_atoi(value);
+                       break;
+               case OPT_InlineMaxSize:
+                       if (value != NULL)
+                               opt_InlineMaxSize = os_atoi(value);
+                       break;
+               case OPT_InlineMinSize:
+                       if (value != NULL)
+                               opt_InlineMinSize = os_atoi(value);
+                       break;
+ #endif
+ #endif
+               case OPT_PrintConfig:
+                       opt_PrintConfig = enable;
+                       break;
+               case OPT_ProfileGCMemoryUsage:
+                       if (value == NULL)
+                               opt_ProfileGCMemoryUsage = 5;
+                       else
+                               opt_ProfileGCMemoryUsage = os_atoi(value);
+                       break;
+               case OPT_ProfileMemoryUsage:
+                       if (value == NULL)
+                               opt_ProfileMemoryUsage = 5;
+                       else
+                               opt_ProfileMemoryUsage = os_atoi(value);
+ # if defined(ENABLE_STATISTICS)
+                       /* we also need statistics */
+                       opt_stat = true;
+ # endif
+                       break;
+               case OPT_ProfileMemoryUsageGNUPlot:
+                       if (value == NULL)
+                               filename = "profile.dat";
+                       else
+                               filename = value;
+                       file = fopen(filename, "w");
+                       if (file == NULL)
+                               vm_abort_errno("options_xx: fopen failed");
+                       opt_ProfileMemoryUsageGNUPlot = file;
+                       break;
+ #if defined(ENABLE_REPLACEMENT)
+               case OPT_TestReplacement:
+                       opt_TestReplacement = enable;
+                       break;
+ #endif
+               case OPT_TraceCompilerCalls:
+                       opt_TraceCompilerCalls = enable;
+                       break;
+               case OPT_TraceExceptions:
+                       opt_TraceExceptions = enable;
+                       break;
+               case OPT_TraceHPI:
+                       opt_TraceHPI = enable;
+                       break;
+ #if defined(ENABLE_INLINING) && !defined(NDEBUG)
+               case OPT_TraceInlining:
+                       if (value == NULL)
+                               opt_TraceInlining = 1;
+                       else
+                               opt_TraceInlining = os_atoi(value);
+                       break;
+ #endif
+               case OPT_TraceJavaCalls:
+                       opt_verbosecall = enable;
+                       opt_TraceJavaCalls = enable;
+                       break;
+               case OPT_TraceJNICalls:
+                       opt_TraceJNICalls = enable;
+                       break;
+               case OPT_TraceJVMCalls:
+                       opt_TraceJVMCalls = enable;
+                       break;
+               case OPT_TraceJVMCallsVerbose:
+                       opt_TraceJVMCallsVerbose = enable;
+                       break;
+               case OPT_TraceLinkClass:
+                       opt_TraceLinkClass = enable;
+                       break;
+ #if defined(ENABLE_REPLACEMENT)
+               case OPT_TraceReplacement:
+                       if (value == NULL)
+                               opt_TraceReplacement = 1;
+                       else
+                               opt_TraceReplacement = os_atoi(value);
+                       break;
+ #endif
+               case OPT_TraceSubsystemInitialization:
+                       opt_TraceSubsystemInitialization = enable;
+                       break;
+               case OPT_TraceTraps:
+                       opt_TraceTraps = enable;
+                       break;
+ #if defined(ENABLE_VMLOG)
+               case OPT_Vmlog:
+                       if (value == NULL)
+                               vmlog_cacao_set_prefix("vmlog");
+                       else
+                               vmlog_cacao_set_prefix(value);
+                       opt_verbosecall = 1;
+                       opt_TraceJavaCalls = 1;
+                       break;
+               case OPT_VmlogStrings:
+                       if (value != NULL)
+                               vmlog_cacao_set_stringprefix(value);
+                       break;
+               case OPT_VmlogIgnore:
+                       if (value != NULL)
+                               vmlog_cacao_set_ignoreprefix(value);
+                       break;
+ #endif
+               default:
+                       printf("Unknown -XX option: %s\n", name);
+                       break;
+               }
+       }
+ }
+ /*
+  * These are local overrides for various environment variables in Emacs.
+  * Please do not remove this and leave it at the end of the file, where
+  * Emacs will automagically detect them.
+  * ---------------------------------------------------------------------
+  * Local variables:
+  * mode: c
+  * indent-tabs-mode: t
+  * c-basic-offset: 4
+  * tab-width: 4
+  * End:
+  */
index 0000000000000000000000000000000000000000,40da2a9b5e9731697c3564ce25912647195b7a9d..28fdf1d6da0090996f3ef93f336ce1c6b4a9a32a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,278 +1,281 @@@
+ /* src/vm/options.h - define global options extern
+    Copyright (C) 1996-2005, 2006, 2007, 2008
+    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+    This file is part of CACAO.
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2, or (at
+    your option) any later version.
+    This program is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+    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., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+ */
+ #ifndef _OPTIONS_H
+ #define _OPTIONS_H
+ #include "config.h"
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ #include <stdint.h>
+ #include "vm/types.h"
+ #include "native/jni.h"
+ #include "vm/global.h"
+ /* reserved option numbers ****************************************************/
+ /* define these negative since the other options are an enum */
+ #define OPT_DONE       -1
+ #define OPT_ERROR      -2
+ #define OPT_IGNORE     -3
+ typedef struct opt_struct opt_struct;
+ struct opt_struct {
+       const char *name;
+       bool        arg;
+       int         value;
+ };
+ typedef struct option_t option_t;
+ struct option_t {
+       const char *name;
+       int         value;
+       int         type;
+       const char *doc;
+ };
+ /* global variables ***********************************************************/
+ extern s4    opt_index;
+ extern char *opt_arg;
+ extern bool opt_foo;
+ extern bool opt_jit;
+ extern bool opt_intrp;
+ extern bool opt_jar;
+ extern bool opt_run;
+ extern s4   opt_heapmaxsize;
+ extern s4   opt_heapstartsize;
+ extern s4   opt_stacksize;
+ extern bool opt_verbose;
+ extern bool opt_debugcolor;
+ extern bool compileall;
+ extern bool loadverbose;         /* Print debug messages during loading */
+ extern bool initverbose;         /* Log class initialization */ 
+ extern bool opt_verboseclass;
+ extern bool opt_verbosegc;
+ extern bool opt_verbosejni;
+ extern bool opt_verbosecall;
+ extern bool showmethods;
+ extern bool showconstantpool;
+ extern bool showutf;
+ extern char *opt_method;
+ extern char *opt_signature;
+ extern bool compileverbose;
+ extern bool showstack;
+ extern bool opt_showdisassemble;
+ extern bool opt_shownops;
+ extern bool opt_showddatasegment;
+ extern bool opt_showintermediate;
+ extern bool checkbounds;
+ extern bool opt_noieee;
+ extern bool checksync;
+ #if defined(ENABLE_LOOP)
+ extern bool opt_loops;
+ #endif
+ extern bool makeinitializations;
+ #if defined(ENABLE_STATISTICS)
+ extern bool opt_stat;
+ extern bool opt_getloadingtime;
+ extern bool opt_getcompilingtime;
+ #endif
+ #if defined(ENABLE_VERIFIER)
+ extern bool opt_verify;
+ #endif
+ #if defined(ENABLE_PROFILING)
+ extern bool opt_prof;
+ extern bool opt_prof_bb;
+ #endif
+ /* optimization options *******************************************************/
+ #if defined(ENABLE_IFCONV)
+ extern bool opt_ifconv;
+ #endif
+ #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+ extern bool opt_lsra;
+ #endif
+ #if defined(ENABLE_SSA)
+ extern bool opt_ssa_dce;          /* enable dead code elemination */
+ extern bool opt_ssa_cp;           /* enable copy propagation      */
+ #endif
+ /* interpreter options ********************************************************/
+ #if defined(ENABLE_INTRP)
+ extern bool opt_no_dynamic;
+ extern bool opt_no_replication;
+ extern bool opt_no_quicksuper;
+ extern s4   opt_static_supers;
+ extern bool vm_debug;
+ #endif
+ /* debug output filtering options *********************************************/
+ #if defined(ENABLE_DEBUG_FILTER)
+ extern const char *opt_filter_verbosecall_include;
+ extern const char *opt_filter_verbosecall_exclude;
+ extern const char *opt_filter_show_method;
+ #endif
+ /* -XX options ****************************************************************/
+ /* NOTE: For better readability keep these alpha-sorted. */
+ /* Options which must always be available (production options in
+    HotSpot). */
+ extern int64_t  opt_MaxDirectMemorySize;
+ extern int      opt_MaxPermSize;
+ extern int      opt_PermSize;
+ extern int      opt_ThreadStackSize;
+ /* Debugging options which can be turned off. */
+ extern int      opt_DebugExceptions;
+ extern int      opt_DebugFinalizer;
++#if defined(ENABLE_JITCACHE)
++extern int      opt_DebugJitCache;
++#endif
+ extern int      opt_DebugLocalReferences;
+ extern int      opt_DebugLocks;
+ extern int      opt_DebugPatcher;
+ extern int      opt_DebugPackage;
+ extern int      opt_DebugProperties;
+ extern int      opt_DebugStackFrameInfo;
+ extern int      opt_DebugStackTrace;
+ extern int      opt_DebugThreads;
+ #if defined(ENABLE_DISASSEMBLER)
+ extern int      opt_DisassembleStubs;
+ #endif
+ #if defined(ENABLE_OPAGENT)
+ extern int      opt_EnableOpagent;
+ #endif
+ #if defined(ENABLE_GC_CACAO)
+ extern int      opt_GCDebugRootSet;
+ extern int      opt_GCStress;
+ #endif
+ #if defined(ENABLE_INLINING)
+ extern int      opt_Inline;
+ #if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
+ extern int      opt_InlineAll;
+ extern int      opt_InlineCount;
+ extern int      opt_InlineMaxSize;
+ extern int      opt_InlineMinSize;
+ #endif
+ #endif
+ extern int      opt_PrintConfig;
+ extern int      opt_ProfileGCMemoryUsage;
+ extern int      opt_ProfileMemoryUsage;
+ extern FILE    *opt_ProfileMemoryUsageGNUPlot;
+ #if defined(ENABLE_REPLACEMENT)
+ extern int      opt_TestReplacement;
+ #endif
+ extern int      opt_TraceCompilerCalls;
+ extern int      opt_TraceExceptions;
+ extern int      opt_TraceHPI;
+ #if defined(ENABLE_INLINING) && !defined(NDEBUG)
+ extern int      opt_TraceInlining;
+ #endif
+ extern int      opt_TraceJavaCalls;
+ extern int      opt_TraceJNICalls;
+ extern int      opt_TraceJVMCalls;
+ extern int      opt_TraceJVMCallsVerbose;
+ extern int      opt_TraceLinkClass;
+ #if defined(ENABLE_REPLACEMENT)
+ extern int      opt_TraceReplacement;
+ #endif
+ extern int      opt_TraceSubsystemInitialization;
+ extern int      opt_TraceTraps;
+ /* function prototypes ********************************************************/
+ int  options_get(opt_struct *opts, JavaVMInitArgs *vm_args);
+ void options_xx(JavaVMInitArgs *vm_args);
+ /* debug **********************************************************************/
+ #if !defined(NDEBUG)
+ # define TRACESUBSYSTEMINITIALIZATION(text)                                           \
+     do {                                                                                                              \
+         if (opt_TraceSubsystemInitialization) {                                       \
+             log_println("[Initializing subsystem: %s]", text);        \
+         }                                                                                                             \
+     } while (0)
+ #else
+ # define TRACESUBSYSTEMINITIALIZATION(text)
+ #endif
+ #ifdef __cplusplus
+ }
+ #endif
+ #endif /* _OPTIONS_H */
+ /*
+  * These are local overrides for various environment variables in Emacs.
+  * Please do not remove this and leave it at the end of the file, where
+  * Emacs will automagically detect them.
+  * ---------------------------------------------------------------------
+  * Local variables:
+  * mode: c
+  * indent-tabs-mode: t
+  * c-basic-offset: 4
+  * tab-width: 4
+  * End:
+  */
diff --cc src/vm/os.hpp
index 0000000000000000000000000000000000000000,7ee25a8f1550d337378238dcaae5bf74eb2ac361..243ffc06fc5de1e3c9b166dbb71e0005953f4129
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,600 +1,609 @@@
+ /* src/vm/os.hpp - system (OS) functions
+    Copyright (C) 2007, 2008
+    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+    This file is part of CACAO.
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2, or (at
+    your option) any later version.
+    This program is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+    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., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+ */
+ #ifndef _OS_HPP
+ #define _OS_HPP
+ #include "config.h"
+ /* NOTE: In this file we check for all system headers, because we wrap
+    all system calls into inline functions for better portability. */
+ #if defined(HAVE_DIRENT_H)
+ # include <dirent.h>
+ #endif
+ #if defined(HAVE_DLFCN_H)
+ # include <dlfcn.h>
+ #endif
+ #if defined(HAVE_ERRNO_H)
+ # include <errno.h>
+ #endif
+ #if defined(HAVE_FCNTL_H)
+ # include <fcntl.h>
+ #endif
+ #if defined(ENABLE_JRE_LAYOUT)
+ # if defined(HAVE_LIBGEN_H)
+ #  include <libgen.h>
+ # endif
+ #endif
+ #if defined(HAVE_SIGNAL_H)
+ # include <signal.h>
+ #endif
+ #if defined(HAVE_STDINT_H)
+ # include <stdint.h>
+ #endif
+ #if defined(HAVE_STDIO_H)
+ # include <stdio.h>
+ #endif
+ #if defined(HAVE_STDLIB_H)
+ # include <stdlib.h>
+ #endif
+ #if defined(HAVE_STRING_H)
+ # include <string.h>
+ #endif
+ #if defined(HAVE_UNISTD_H)
+ # include <unistd.h>
+ #endif
+ #if defined(HAVE_SYS_MMAN_H)
+ # include <sys/mman.h>
+ #endif
+ #if defined(HAVE_SYS_SOCKET_H)
+ # include <sys/socket.h>
+ #endif
+ #if defined(HAVE_SYS_STAT_H)
+ # include <sys/stat.h>
+ #endif
+ #if defined(HAVE_SYS_TYPES_H)
+ # include <sys/types.h>
+ #endif
+ #ifdef __cplusplus
+ // Class wrapping system (OS) functions.
+ class os {
+ public:
+       // Inline functions.
+       static inline void   abort();
+       static inline int    accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
+       static inline int    access(const char *pathname, int mode);
+       static inline int    atoi(const char* nptr);
+       static inline void*  calloc(size_t nmemb, size_t size);
+       static inline int    close(int fd);
+       static inline int    connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen);
+ #if defined(ENABLE_JRE_LAYOUT)
+       static inline char*  dirname(char* path);
+ #endif
+       static inline int    dlclose(void* handle);
+       static inline char*  dlerror(void);
+       static inline void*  dlopen(const char* filename, int flag);
+       static inline void*  dlsym(void* handle, const char* symbol);
+       static inline int    fclose(FILE* fp);
+       static inline FILE*  fopen(const char* path, const char* mode);
+       static inline size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
+       static inline void   free(void* ptr);
+       static inline int    gethostname(char* name, size_t len);
+       static inline int    getpagesize(void);
+       static inline int    getsockname(int s, struct sockaddr* name, socklen_t* namelen);
+       static inline int    getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen);
+       static inline int    listen(int sockfd, int backlog);
+       static inline void*  malloc(size_t size);
+       static inline void*  memcpy(void* dest, const void* src, size_t n);
+       static inline void*  memset(void* s, int c, size_t n);
+       static inline int    mprotect(void* addr, size_t len, int prot);
+       static inline int    scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
+       static inline int    setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen);
+       static inline int    shutdown(int s, int how);
+       static inline int    socket(int domain, int type, int protocol);
+       static inline int    stat(const char* path, struct stat* buf);
+ #if defined(__SOLARIS__)
+       static inline int    str2sig(const char* str, int* signum);
+ #endif
+       static inline char*  strcat(char* dest, const char* src);
+       static inline char*  strcpy(char* dest, const char* src);
+       static inline char*  strdup(const char* s);
+       static inline size_t strlen(const char* s);
+       static inline char*  strerror(int errnum);
+       static void* mmap_anonymous(void *addr, size_t len, int prot, int flags);
+       static int   processors_online(void);
+ };
+ inline void os::abort(void)
+ {
+ #if defined(HAVE_ABORT)
+       ::abort();
+ #else
+ # error abort not available
+ #endif
+ }
+ inline int os::accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen)
+ {
+ #if defined(HAVE_ACCEPT)
+       return ::accept(sockfd, addr, addrlen);
+ #else
+ # error accept not available
+ #endif
+ }
+ inline int os::access(const char* pathname, int mode)
+ {
+ #if defined(HAVE_ACCESS)
+       return ::access(pathname, mode);
+ #else
+ # error access not available
+ #endif
+ }
+ inline int os::atoi(const char* nptr)
+ {
+ #if defined(HAVE_ATOI)
+       return ::atoi(nptr);
+ #else
+ # error atoi not available
+ #endif
+ }
+ inline void* os::calloc(size_t nmemb, size_t size)
+ {
+ #if defined(HAVE_CALLOC)
+       return ::calloc(nmemb, size);
+ #else
+ # error calloc not available
+ #endif
+ }
+ inline int os::close(int fd)
+ {
+ #if defined(HAVE_CLOSE)
+       return ::close(fd);
+ #else
+ # error close not available
+ #endif
+ }
+ inline int os::connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen)
+ {
+ #if defined(HAVE_CONNECT)
+       return ::connect(sockfd, serv_addr, addrlen);
+ #else
+ # error connect not available
+ #endif
+ }
+ #if defined(ENABLE_JRE_LAYOUT)
+ inline char* os::dirname(char* path)
+ {
+ #if defined(HAVE_DIRNAME)
+       return ::dirname(path);
+ #else
+ # error dirname not available
+ #endif
+ }
+ #endif
+ inline int os::dlclose(void* handle)
+ {
+ #if defined(HAVE_DLCLOSE)
+       return ::dlclose(handle);
+ #else
+ # error dlclose not available
+ #endif
+ }
+ inline char* os::dlerror(void)
+ {
+ #if defined(HAVE_DLERROR)
+       return ::dlerror();
+ #else
+ # error dlerror not available
+ #endif
+ }
+ inline void* os::dlopen(const char* filename, int flag)
+ {
+ #if defined(HAVE_DLOPEN)
+       return ::dlopen(filename, flag);
+ #else
+ # error dlopen not available
+ #endif
+ }
+ inline void* os::dlsym(void* handle, const char* symbol)
+ {
+ #if defined(HAVE_DLSYM)
+       return ::dlsym(handle, symbol);
+ #else
+ # error dlsym not available
+ #endif
+ }
+ inline int os::fclose(FILE* fp)
+ {
+ #if defined(HAVE_FCLOSE)
+       return ::fclose(fp);
+ #else
+ # error fclose not available
+ #endif
+ }
+ inline FILE* os::fopen(const char* path, const char* mode)
+ {
+ #if defined(HAVE_FOPEN)
+       return ::fopen(path, mode);
+ #else
+ # error fopen not available
+ #endif
+ }
+ inline size_t os::fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
+ {
+ #if defined(HAVE_FREAD)
+       return ::fread(ptr, size, nmemb, stream);
+ #else
+ # error fread not available
+ #endif
+ }
++inline static int system_fseek(FILE *stream, off_t offset, int whence)
++{
++#if defined(HAVE_FSEEK)
++      return fseek(stream, offset, whence);
++#else
++# error fseek not available
++#endif
++}
++
+ inline void os::free(void* ptr)
+ {
+ #if defined(HAVE_FREE)
+       ::free(ptr);
+ #else
+ # error free not available
+ #endif
+ }
+ inline static int system_fsync(int fd)
+ {
+ #if defined(HAVE_FSYNC)
+       return fsync(fd);
+ #else
+ # error fsync not available
+ #endif
+ }
+ inline static int system_ftruncate(int fd, off_t length)
+ {
+ #if defined(HAVE_FTRUNCATE)
+       return ftruncate(fd, length);
+ #else
+ # error ftruncate not available
+ #endif
+ }
+ inline int os::gethostname(char* name, size_t len)
+ {
+ #if defined(HAVE_GETHOSTNAME)
+       return ::gethostname(name, len);
+ #else
+ # error gethostname not available
+ #endif
+ }
+ inline int os::getpagesize(void)
+ {
+ #if defined(HAVE_GETPAGESIZE)
+       return ::getpagesize();
+ #else
+ # error getpagesize not available
+ #endif
+ }
+ inline int os::getsockname(int s, struct sockaddr* name, socklen_t* namelen)
+ {
+ #if defined(HAVE_GETSOCKNAME)
+       return ::getsockname(s, name, namelen);
+ #else
+ # error getsockname not available
+ #endif
+ }
+ inline int os::getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen)
+ {
+ #if defined(HAVE_GETSOCKOPT)
+       return ::getsockopt(s, level, optname, optval, optlen);
+ #else
+ # error getsockopt not available
+ #endif
+ }
+ inline int os::listen(int sockfd, int backlog)
+ {
+ #if defined(HAVE_LISTEN)
+       return ::listen(sockfd, backlog);
+ #else
+ # error listen not available
+ #endif
+ }
+ inline static off_t system_lseek(int fildes, off_t offset, int whence)
+ {
+ #if defined(HAVE_LSEEK)
+       return lseek(fildes, offset, whence);
+ #else
+ # error lseek not available
+ #endif
+ }
+ inline void* os::malloc(size_t size)
+ {
+ #if defined(HAVE_MALLOC)
+       return ::malloc(size);
+ #else
+ # error malloc not available
+ #endif
+ }
+ inline void* os::memcpy(void* dest, const void* src, size_t n)
+ {
+ #if defined(HAVE_MEMCPY)
+       return ::memcpy(dest, src, n);
+ #else
+ # error memcpy not available
+ #endif
+ }
+ inline void* os::memset(void* s, int c, size_t n)
+ {
+ #if defined(HAVE_MEMSET)
+       return ::memset(s, c, n);
+ #else
+ # error memset not available
+ #endif
+ }
+ inline int os::mprotect(void* addr, size_t len, int prot)
+ {
+ #if defined(HAVE_MPROTECT)
+       return ::mprotect(addr, len, prot);
+ #else
+ # error mprotect not available
+ #endif
+ }
+ inline static int system_open(const char *pathname, int flags, mode_t mode)
+ {
+ #if defined(HAVE_OPEN)
+       return open(pathname, flags, mode);
+ #else
+ # error open not available
+ #endif
+ }
+ inline static ssize_t system_read(int fd, void *buf, size_t count)
+ {
+ #if defined(HAVE_READ)
+       return read(fd, buf, count);
+ #else
+ # error read not available
+ #endif
+ }
+ inline static void *system_realloc(void *ptr, size_t size)
+ {
+ #if defined(HAVE_REALLOC)
+       return realloc(ptr, size);
+ #else
+ # error realloc not available
+ #endif
+ }
+ inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *))
+ /*
+ #elif defined(__SOLARIS__)
+ inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const struct dirent **, const struct dirent **))
+ #elif defined(__IRIX__)
+ inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(dirent_t *), int(*compar)(dirent_t **, dirent_t **))
+ #else
+ inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(struct dirent *), int(*compar)(const void *, const void *))
+ #endif
+ */
+ {
+ #if defined(HAVE_SCANDIR)
+ # if defined(__LINUX__)
+       return ::scandir(dir, namelist, filter, compar);
+ #elif defined(__SOLARIS__)
+       return ::scandir(dir, namelist, filter, (int (*)(const dirent**, const dirent**)) compar);
+ # else
+       return ::scandir(dir, namelist, (int (*)(struct dirent*)) filter, compar);
+ # endif
+ #else
+ # error scandir not available
+ #endif
+ }
+ inline int os::setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen)
+ {
+ #if defined(HAVE_SETSOCKOPT)
+       return ::setsockopt(s, level, optname, optval, optlen);
+ #else
+ # error setsockopt not available
+ #endif
+ }
+ inline int os::shutdown(int s, int how)
+ {
+ #if defined(HAVE_SHUTDOWN)
+       return ::shutdown(s, how);
+ #else
+ # error shutdown not available
+ #endif
+ }
+ inline int os::socket(int domain, int type, int protocol)
+ {
+ #if defined(HAVE_SOCKET)
+       return ::socket(domain, type, protocol);
+ #else
+ # error socket not available
+ #endif
+ }
+ inline int os::stat(const char* path, struct stat* buf)
+ {
+ #if defined(HAVE_STAT)
+       return ::stat(path, buf);
+ #else
+ # error stat not available
+ #endif
+ }
+ #if defined(__SOLARIS__)
+ inline int os::str2sig(const char* str, int* signum)
+ {
+ #if defined(HAVE_STR2SIG)
+       return ::str2sig(str, signum);
+ #else
+ # error str2sig not available
+ #endif
+ }
+ #endif
+ inline char* os::strcat(char* dest, const char* src)
+ {
+ #if defined(HAVE_STRCAT)
+       return ::strcat(dest, src);
+ #else
+ # error strcat not available
+ #endif
+ }
+ inline char* os::strcpy(char* dest, const char* src)
+ {
+ #if defined(HAVE_STRCPY)
+       return ::strcpy(dest, src);
+ #else
+ # error strcpy not available
+ #endif
+ }
+ inline char* os::strdup(const char* s)
+ {
+ #if defined(HAVE_STRDUP)
+       return ::strdup(s);
+ #else
+ # error strdup not available
+ #endif
+ }
+ inline char* os::strerror(int errnum)
+ {
+ #if defined(HAVE_STRERROR)
+       return ::strerror(errnum);
+ #else
+ # error strerror not available
+ #endif
+ }
+ inline size_t os::strlen(const char* s)
+ {
+ #if defined(HAVE_STRLEN)
+       return ::strlen(s);
+ #else
+ # error strlen not available
+ #endif
+ }
+ inline static ssize_t system_write(int fd, const void *buf, size_t count)
+ {
+ #if defined(HAVE_WRITE)
+       return write(fd, buf, count);
+ #else
+ # error write not available
+ #endif
+ }
+ #else
+ void*  os_mmap_anonymous(void *addr, size_t len, int prot, int flags);
+ void   os_abort(void);
+ int    os_access(const char* pathname, int mode);
+ int    os_atoi(const char* nptr);
+ void*  os_calloc(size_t nmemb, size_t size);
+ char*  os_dirname(char* path);
+ int    os_dlclose(void* handle);
+ char*  os_dlerror(void);
+ void*  os_dlopen(const char* filename, int flag);
+ void*  os_dlsym(void* handle, const char* symbol);
+ int    os_fclose(FILE* fp);
+ FILE*  os_fopen(const char* path, const char* mode);
+ size_t os_fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
+ void   os_free(void* ptr);
+ int    os_getpagesize(void);
+ void*  os_memcpy(void* dest, const void* src, size_t n);
+ void*  os_memset(void* s, int c, size_t n);
+ int    os_mprotect(void* addr, size_t len, int prot);
+ int    os_scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
+ int    os_stat(const char* path, struct stat* buf);
+ char*  os_strcat(char* dest, const char* src);
+ char*  os_strcpy(char* dest, const char* src);
+ char*  os_strdup(const char* s);
+ int    os_strlen(const char* s);
+ #endif
+ #endif // _OS_HPP
+ /*
+  * These are local overrides for various environment variables in Emacs.
+  * Please do not remove this and leave it at the end of the file, where
+  * Emacs will automagically detect them.
+  * ---------------------------------------------------------------------
+  * Local variables:
+  * mode: c++
+  * indent-tabs-mode: t
+  * c-basic-offset: 4
+  * tab-width: 4
+  * End:
+  * vim:noexpandtab:sw=4:ts=4:
+  */
index 0000000000000000000000000000000000000000,fe3af07016409a9e92d074eab345622e1dc4f36d..73eb721d7dc1b8f2a5bae6abb21bd2585a995a62
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,167 +1,167 @@@
 -/* macro for accessing the class name of a method reference                   */
+ /* src/vm/references.h - references to classes/fields/methods
+    Copyright (C) 1996-2005, 2006, 2007, 2008
+    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+    This file is part of CACAO.
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2, or (at
+    your option) any later version.
+    This program is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+    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., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+ */
+ #ifndef _REFERENCES_H_
+ #define _REFERENCES_H_
+ /* forward typedefs ***********************************************************/
+ typedef struct constant_classref constant_classref;
+ typedef struct constant_FMIref   constant_FMIref;
+ /* constant_classref **********************************************************/
+ struct constant_classref {
+       void             *pseudo_vftbl; /* for distinguishing it from classinfo   */
+       struct classinfo *referer;    /* class containing the reference           */
+       struct utf       *name;       /* name of the class refered to             */
+ };
+ /* classref_or_classinfo ******************************************************/
+ typedef union classref_or_classinfo {
+       constant_classref *ref;       /* a symbolic class reference               */
+       struct classinfo  *cls;       /* an already loaded class                  */
+       void              *any;       /* used for general access (x != NULL,...)  */
+ } classref_or_classinfo;
+ /* parseddesc_t ***************************************************************/
+ typedef union parseddesc {
+       struct typedesc   *fd;        /* parsed field descriptor                  */
+       struct methoddesc *md;        /* parsed method descriptor                 */
+       void              *any;       /* used for simple test against NULL        */
+ } parseddesc_t;
+ #include "config.h"
+ #include "vm/types.h"
+ #include "vm/class.h"
+ #include "vm/descriptor.h"
+ #include "vm/field.h"
+ #include "vm/global.h"
+ #include "vm/method.h"
+ #include "vm/utf8.h"
+ /*----------------------------------------------------------------------------*/
+ /* References                                                                 */
+ /*                                                                            */
+ /* This header files defines the following types used for references to       */
+ /* classes/methods/fields and descriptors:                                    */
+ /*                                                                            */
+ /*     classinfo *                a loaded class                              */
+ /*     constant_classref          a symbolic reference                        */
+ /*     classref_or_classinfo      a loaded class or a symbolic reference      */
+ /*                                                                            */
+ /*     constant_FMIref            a symb. ref. to a field/method/intf.method  */
+ /*                                                                            */
+ /*     typedesc *                 describes a field type                      */
+ /*     methoddesc *               descrives a method type                     */
+ /*     parseddesc                 describes a field type or a method type     */
+ /*----------------------------------------------------------------------------*/
+ /* structs ********************************************************************/
+ /* constant_FMIref ************************************************************/
+ struct constant_FMIref{      /* Fieldref, Methodref and InterfaceMethodref    */
+       union {
+               s4                 index;     /* used only within the loader          */
+               constant_classref *classref;  /* class having this field/meth./intfm. */
+               fieldinfo         *field;     /* resolved field                       */
+               methodinfo        *method;    /* resolved method                      */
+       } p;
+       utf         *name;       /* field/method/interfacemethod name             */
+       utf         *descriptor; /* field/method/intfmeth. type descriptor string */
+       parseddesc_t parseddesc; /* parsed descriptor                             */
+ };
+ /* macros *********************************************************************/
+ /* a value that never occurrs in classinfo.header.vftbl                       */
+ #define CLASSREF_PSEUDO_VFTBL ((void *) 1)
+ /* macro for testing if a classref_or_classinfo is a classref                 */
+ /* `reforinfo` is only evaluated once                                         */
+ #define IS_CLASSREF(reforinfo)  \
+       ((reforinfo).ref->pseudo_vftbl == CLASSREF_PSEUDO_VFTBL)
+ /* macro for testing if a constant_FMIref has been resolved                   */
+ /* `fmiref` is only evaluated once                                            */
+ #define IS_FMIREF_RESOLVED(fmiref)  \
+       ((fmiref)->p.classref->pseudo_vftbl != CLASSREF_PSEUDO_VFTBL)
+ /* the same as IS_CLASSREF, but also check against NULL */
+ #define IS_XCLASSREF(reforinfo)  \
+       ((reforinfo).any && IS_CLASSREF(reforinfo))
+ /* macro for casting a classref/classinfo * to a classref_or_classinfo        */
+ #define CLASSREF_OR_CLASSINFO(value) \
+       (*((classref_or_classinfo *)(&(value))))
+ /* macro for accessing the name of a classref/classinfo                       */
+ #define CLASSREF_OR_CLASSINFO_NAME(value) \
+       (IS_CLASSREF(value) ? (value).ref->name : (value).cls->name)
+ /* macro for accessing the class name of a method reference                   */
+ #define METHODREF_CLASSNAME(fmiref) \
+       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.method->clazz->name \
+                                                               : (fmiref)->p.classref->name)
++/* macro for accessing the class name of a field reference                   */
+ #define FIELDREF_CLASSNAME(fmiref) \
+       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.field->clazz->name \
+                                                               : (fmiref)->p.classref->name)
+ /* initialize a constant_classref with referer `ref` and name `classname`     */
+ #define CLASSREF_INIT(c,ref,classname) \
+     do { \
+         (c).pseudo_vftbl = CLASSREF_PSEUDO_VFTBL; \
+         (c).referer = (ref); \
+         (c).name = (classname); \
+     } while (0)
+ #endif /* _REFERENCES_H_ */
+ /*
+  * These are local overrides for various environment variables in Emacs.
+  * Please do not remove this and leave it at the end of the file, where
+  * Emacs will automagically detect them.
+  * ---------------------------------------------------------------------
+  * Local variables:
+  * mode: c
+  * indent-tabs-mode: t
+  * c-basic-offset: 4
+  * tab-width: 4
+  * End:
+  * vim:noexpandtab:sw=4:ts=4:
+  */
Simple merge
index 0000000000000000000000000000000000000000,d5756ee4fd84cdef348e97f489381e2cd86b7ece..37d19460707d5b98c0cc460a00d44d014a394c92
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,818 +1,822 @@@
 -              size_patchref;
+ /* src/vm/statistics.c - global variables for statistics
+    Copyright (C) 1996-2005, 2006, 2007, 2008
+    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+    This file is part of CACAO.
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2, or (at
+    your option) any later version.
+    This program is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+    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., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+ */
+ #include "config.h"
+ #include <stdint.h>
+ #include <string.h> 
+ #if defined(HAVE_TIME_H)
+ # include <time.h>
+ #endif
+ #if defined(HAVE_SYS_TIME_H)
+ # include <sys/time.h>
+ #endif
+ #if defined(HAVE_SYS_RESOURCE_H)
+ # include <sys/resource.h>
+ #endif
+ #include "vm/types.h"
+ #include "mm/gc.hpp"
+ #include "toolbox/logging.h"
+ #include "vm/class.h"
+ #include "vm/field.h"
+ #include "vm/global.h"
+ #include "vm/method.h"
+ #include "vm/options.h"
+ #include "vm/statistics.h"
+ #include "vm/jit/code.h"
+ /* global variables ***********************************************************/
+ static s8 loadingtime = 0;              /* accumulated loading time           */
+ static s8 loadingstarttime = 0;
+ static s8 loadingstoptime = 0;
+ static s4 loadingtime_recursion = 0;
+ static s8 compilingtime = 0;            /* accumulated compile time           */
+ static s8 compilingstarttime = 0;
+ static s8 compilingstoptime = 0;
+ static s4 compilingtime_recursion = 0;
+ s4 codememusage = 0;
+ s4 maxcodememusage = 0;
+ s4 memoryusage = 0;
+ s4 maxmemusage = 0;
+ s4 maxdumpsize = 0;
+ s4 globalallocateddumpsize = 0;
+ s4 globaluseddumpsize = 0;
+ /* variables for measurements *************************************************/
+ s4 size_classinfo        = 0;
+ s4 size_fieldinfo        = 0;
+ s4 size_methodinfo       = 0;
+ s4 size_lineinfo         = 0;
+ s4 size_codeinfo         = 0;
+ s4 size_stub_native      = 0;
+ s4 size_stack_map        = 0;
+ s4 size_string           = 0;
+ s4 size_threadobject     = 0;
+ int32_t size_thread_index_t = 0;
+ int32_t size_stacksize      = 0;
+ s4 size_lock_record      = 0;
+ s4 size_lock_hashtable   = 0;
+ s4 size_lock_waiter      = 0;
+ int32_t count_linenumbertable = 0;
+ int32_t size_linenumbertable  = 0;
+ s4 size_patchref         = 0;
++s4 size_cachedref          = 0;
++
+ u8 count_calls_java_to_native = 0;
+ u8 count_calls_native_to_java = 0;
+ int count_const_pool_len = 0;
+ int count_classref_len = 0;
+ int count_parsed_desc_len = 0;
+ int count_vftbl_len = 0;
+ int count_all_methods = 0;
+ int count_methods_marked_used = 0;  /* RTA */
+ int count_vmcode_len = 0;
+ int count_extable_len = 0;
+ int count_class_loads = 0;
+ int count_class_inits = 0;
+ int count_utf_len = 0;                  /* size of utf hash                   */
+ int count_utf_new = 0;                  /* calls of utf_new                   */
+ int count_utf_new_found  = 0;           /* calls of utf_new with fast return  */
+ int count_locals_conflicts = 0;         /* register allocator statistics */
+ int count_locals_spilled = 0;
+ int count_locals_register = 0;
+ int count_ss_spilled = 0;
+ int count_ss_register = 0;
+ int count_methods_allocated_by_lsra = 0;
+ int count_mem_move_bb = 0;
+ int count_interface_size = 0;
+ int count_argument_mem_ss = 0;
+ int count_argument_reg_ss = 0;
+ int count_method_in_register = 0;
+ int count_mov_reg_reg = 0;
+ int count_mov_mem_reg = 0;
+ int count_mov_reg_mem = 0;
+ int count_mov_mem_mem = 0;
+ int count_jit_calls = 0;
+ int count_methods = 0;
+ int count_spills_read_ila = 0;
+ int count_spills_read_flt = 0;
+ int count_spills_read_dbl = 0;
+ int count_spills_write_ila = 0;
+ int count_spills_write_flt = 0;
+ int count_spills_write_dbl = 0;
+ int count_pcmd_activ = 0;
+ int count_pcmd_drop = 0;
+ int count_pcmd_zero = 0;
+ int count_pcmd_const_store = 0;
+ int count_pcmd_const_alu = 0;
+ int count_pcmd_const_bra = 0;
+ int count_pcmd_load = 0;
+ int count_pcmd_move = 0;
+ int count_load_instruction = 0;
+ int count_pcmd_store = 0;
+ int count_pcmd_store_comb = 0;
+ int count_dup_instruction = 0;
+ int count_pcmd_op = 0;
+ int count_pcmd_mem = 0;
+ int count_pcmd_met = 0;
+ int count_pcmd_bra = 0;
+ int count_pcmd_table = 0;
+ int count_pcmd_return = 0;
+ int count_pcmd_returnx = 0;
+ int count_check_null = 0;
+ int count_check_bound = 0;
+ int count_max_basic_blocks = 0;
+ int count_basic_blocks = 0;
+ int count_javainstr = 0;
+ int count_max_javainstr = 0;
+ int count_javacodesize = 0;
+ int count_javaexcsize = 0;
+ int count_calls = 0;
+ int count_tryblocks = 0;
+ int count_code_len = 0;
+ int count_data_len = 0;
+ int count_cstub_len = 0;
+ int count_max_new_stack = 0;
+ int count_upper_bound_new_stack = 0;
+ int count_emit_branch = 0;
+ int count_emit_branch_8bit = 0;
+ int count_emit_branch_16bit = 0;
+ int count_emit_branch_32bit = 0;
+ int count_emit_branch_64bit = 0;
+ s4 count_branches_resolved   = 0;
+ s4 count_branches_unresolved = 0;
+ u8 count_jni_callXmethod_calls=0;
+ u8 count_jni_calls=0;
+ static int count_block_stack_init[11] = {
+       0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 
+       0
+ };
+ int *count_block_stack = count_block_stack_init;
+ static int count_analyse_iterations_init[5] = {
+       0, 0, 0, 0, 0
+ };
+ int *count_analyse_iterations = count_analyse_iterations_init;
+ static int count_method_bb_distribution_init[9] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0
+ };
+ int *count_method_bb_distribution = count_method_bb_distribution_init;
+ static int count_block_size_distribution_init[18] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0
+ };
+ int *count_block_size_distribution = count_block_size_distribution_init;
+ static int count_store_length_init[21] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0
+ };
+ int *count_store_length = count_store_length_init;
+ static int count_store_depth_init[11] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0
+ };
+ int *count_store_depth = count_store_depth_init;
+ /* instruction scheduler statistics *******************************************/
+ s4 count_schedule_basic_blocks = 0;
+ s4 count_schedule_nodes = 0;
+ s4 count_schedule_leaders = 0;
+ s4 count_schedule_max_leaders = 0;
+ s4 count_schedule_critical_path = 0;
+ /* jnicallXmethodinvokation ***************************************************
+    increments the jni CallXMethod invokation count by one
+       
+ *******************************************************************************/
+ void jnicallXmethodnvokation(void)
+ {
+       /* XXX do locking here */
+       count_jni_callXmethod_calls++;
+ }
+ /* jniinvokation *************************************************************
+    increments the jni overall  invokation count by one
+       
+ *******************************************************************************/
+ void jniinvokation(void)
+ {
+       /* XXX do locking here */
+       count_jni_calls++;
+ }
+ /* getcputime *********************************** ******************************
+    Returns the used CPU time in microseconds
+       
+ *******************************************************************************/
+ s8 getcputime(void)
+ {
+ #if defined(HAVE_GETRUSAGE)
+       struct rusage ru;
+       int sec, usec;
+       getrusage(RUSAGE_SELF, &ru);
+       sec  = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec;
+       usec = ru.ru_utime.tv_usec + ru.ru_stime.tv_usec;
+       return sec * 1000000 + usec;
+ #else
+       /* If we don't have getrusage, simply return 0. */
+       return 0;
+ #endif
+ }
+ /* loadingtime_stop ************************************************************
+    XXX
+ *******************************************************************************/
+ void loadingtime_start(void)
+ {
+       loadingtime_recursion++;
+       if (loadingtime_recursion == 1)
+               loadingstarttime = getcputime();
+ }
+ /* loadingtime_stop ************************************************************
+    XXX
+ *******************************************************************************/
+ void loadingtime_stop(void)
+ {
+       if (loadingtime_recursion == 1) {
+               loadingstoptime = getcputime();
+               loadingtime += (loadingstoptime - loadingstarttime);
+       }
+       loadingtime_recursion--;
+ }
+ /* compilingtime_stop **********************************************************
+    XXX
+ *******************************************************************************/
+ void compilingtime_start(void)
+ {
+       compilingtime_recursion++;
+       if (compilingtime_recursion == 1)
+               compilingstarttime = getcputime();
+ }
+ /* compilingtime_stop **********************************************************
+    XXX
+ *******************************************************************************/
+ void compilingtime_stop(void)
+ {
+       if (compilingtime_recursion == 1) {
+               compilingstoptime = getcputime();
+               compilingtime += (compilingstoptime - compilingstarttime);
+       }
+       compilingtime_recursion--;
+ }
+ /* print_times *****************************************************************
+    Prints a summary of CPU time usage.
+ *******************************************************************************/
+ void print_times(void)
+ {
+       s8 totaltime;
+       s8 runtime;
+       totaltime = getcputime();
+       runtime = totaltime - loadingtime - compilingtime;
+ #if SIZEOF_VOID_P == 8
+       dolog("Time for loading classes: %6ld ms", loadingtime / 1000);
+       dolog("Time for compiling code:  %6ld ms", compilingtime / 1000);
+       dolog("Time for running program: %6ld ms", runtime / 1000);
+       dolog("Total time:               %6ld ms", totaltime / 1000);
+ #else
+       dolog("Time for loading classes: %6lld ms", loadingtime / 1000);
+       dolog("Time for compiling code:  %6lld ms", compilingtime / 1000);
+       dolog("Time for running program: %6lld ms", runtime / 1000);
+       dolog("Total time:               %6lld ms", totaltime / 1000);
+ #endif
+ }
+ /* print_stats *****************************************************************
+    outputs detailed compiler statistics
+ *******************************************************************************/
+ void print_stats(void)
+ {
+       s4    i;
+       float f;
+       s4    sum;
+       dolog("Number of JIT compiler calls: %6d", count_jit_calls);
+       dolog("Number of compiled methods:   %6d", count_methods);
+       dolog("Number of compiled basic blocks:               %6d",
+                 count_basic_blocks);
+       dolog("Number of max. basic blocks per method:        %6d",
+                 count_max_basic_blocks);
+       dolog("Number of compiled JavaVM instructions:        %6d",
+                 count_javainstr);
+       dolog("Number of max. JavaVM instructions per method: %6d",
+                 count_max_javainstr);
+       dolog("Size of compiled JavaVM instructions:          %6d(%d)",
+                 count_javacodesize, count_javacodesize - count_methods * 18);
+       dolog("Size of compiled Exception Tables:      %d", count_javaexcsize);
+       dolog("Number of Machine-Instructions: %d", count_code_len >> 2);
+       dolog("Number of Spills (write to memory) <all [i/l/a|flt|dbl]>: %d [%d|%d|%d]",
+               count_spills_write_ila + count_spills_write_flt + count_spills_write_dbl,
+               count_spills_write_ila, count_spills_write_flt, count_spills_write_dbl);
+       dolog("Number of Spills (read from memory) <all [i/l/a|flt|dbl]>: %d [%d|%d|%d]",
+               count_spills_read_ila + count_spills_read_flt + count_spills_read_dbl,
+               count_spills_read_ila, count_spills_read_flt, count_spills_read_dbl);
+       dolog("Number of Activ    Pseudocommands: %6d", count_pcmd_activ);
+       dolog("Number of Drop     Pseudocommands: %6d", count_pcmd_drop);
+       dolog("Number of Const    Pseudocommands: %6d (zero:%5d)",
+                 count_pcmd_load, count_pcmd_zero);
+       dolog("Number of ConstAlu Pseudocommands: %6d (cmp: %5d, store:%5d)",
+                 count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
+       dolog("Number of Move     Pseudocommands: %6d", count_pcmd_move);
+       dolog("Number of Load     Pseudocommands: %6d", count_load_instruction);
+       dolog("Number of Store    Pseudocommands: %6d (combined: %5d)",
+                 count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
+       dolog("Number of OP       Pseudocommands: %6d", count_pcmd_op);
+       dolog("Number of DUP      Pseudocommands: %6d", count_dup_instruction);
+       dolog("Number of Mem      Pseudocommands: %6d", count_pcmd_mem);
+       dolog("Number of Method   Pseudocommands: %6d", count_pcmd_met);
+       dolog("Number of Branch   Pseudocommands: %6d (rets:%5d, Xrets: %5d)",
+                 count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
+       log_println("                resolved branches: %6d", count_branches_resolved);
+       log_println("              unresolved branches: %6d", count_branches_unresolved);
+       dolog("Number of Table    Pseudocommands: %6d", count_pcmd_table);
+       dolog("Number of Useful   Pseudocommands: %6d", count_pcmd_table +
+                 count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
+       dolog("Number of Null Pointer Checks:     %6d", count_check_null);
+       dolog("Number of Array Bound Checks:      %6d", count_check_bound);
+       dolog("Number of Try-Blocks: %d", count_tryblocks);
+       dolog("Number of branch_emit (total, 8bit/16bit/32bit/64bit offset): %d, %d/%d/%d/%d",
+               count_emit_branch,  count_emit_branch_8bit,  count_emit_branch_16bit, 
+                                                       count_emit_branch_32bit, count_emit_branch_64bit);
+       dolog("Maximal count of stack elements:   %d", count_max_new_stack);
+       dolog("Upper bound of max stack elements: %d", count_upper_bound_new_stack);
+       dolog("Distribution of stack sizes at block boundary");
+       dolog("     0     1     2     3     4     5     6     7     8     9  >=10");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_block_stack[0], count_block_stack[1], count_block_stack[2],
+                 count_block_stack[3], count_block_stack[4], count_block_stack[5],
+                 count_block_stack[6], count_block_stack[7], count_block_stack[8],
+                 count_block_stack[9], count_block_stack[10]);
+       dolog("Distribution of store stack depth");
+       dolog("     0     1     2     3     4     5     6     7     8     9  >=10");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_store_depth[0], count_store_depth[1], count_store_depth[2],
+                 count_store_depth[3], count_store_depth[4], count_store_depth[5],
+                 count_store_depth[6], count_store_depth[7], count_store_depth[8],
+                 count_store_depth[9], count_store_depth[10]);
+       dolog("Distribution of store creator chains first part");
+       dolog("     0     1     2     3     4     5     6     7     8     9");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_store_length[0], count_store_length[1], count_store_length[2],
+                 count_store_length[3], count_store_length[4], count_store_length[5],
+                 count_store_length[6], count_store_length[7], count_store_length[8],
+                 count_store_length[9]);
+       dolog("Distribution of store creator chains second part");
+       dolog("    10    11    12    13    14    15    16    17    18    19  >=20");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_store_length[10], count_store_length[11],
+                 count_store_length[12], count_store_length[13],
+                 count_store_length[14], count_store_length[15],
+                 count_store_length[16], count_store_length[17],
+                 count_store_length[18], count_store_length[19],
+                 count_store_length[20]);
+       dolog("Distribution of analysis iterations");
+       dolog("     1     2     3     4   >=5");
+       dolog("%6d%6d%6d%6d%6d",
+                 count_analyse_iterations[0], count_analyse_iterations[1],
+                 count_analyse_iterations[2], count_analyse_iterations[3],
+                 count_analyse_iterations[4]);
+       /* Distribution of basic blocks per method ********************************/
+       log_println("Distribution of basic blocks per method:");
+       log_println("   <=5  <=10  <=15  <=20  <=30  <=40  <=50  <=75   >75");
+       log_start();
+       for (i = 0; i <= 8; i++)
+               log_print("%6d", count_method_bb_distribution[i]);
+       log_finish();
+       /* print ratio */
+       f = (float) count_methods;
+       log_start();
+       for (i = 0; i <= 8; i++)
+               log_print("%6.2f", (float) count_method_bb_distribution[i] / f);
+       log_finish();
+       /* print cumulated ratio */
+       log_start();
+       for (i = 0, sum = 0; i <= 8; i++) {
+               sum += count_method_bb_distribution[i];
+               log_print("%6.2f", (float) sum / f);
+       }
+       log_finish();
+       /* Distribution of basic block sizes **************************************/
+       log_println("Distribution of basic block sizes:");
+       log_println("     0     1     2     3     4     5     6     7     8     9   <13   <15   <17   <19   <21   <26   <31   >30");
+       /* print block sizes */
+       log_start();
+       for (i = 0; i <= 17; i++)
+               log_print("%6d", count_block_size_distribution[i]);
+       log_finish();
+       /* print ratio */
+       f = (float) count_basic_blocks;
+       log_start();
+       for (i = 0; i <= 17; i++)
+               log_print("%6.2f", (float) count_block_size_distribution[i] / f);
+       log_finish();
+       /* print cumulated ratio */
+       log_start();
+       for (i = 0, sum = 0; i <= 17; i++) {
+               sum += count_block_size_distribution[i];
+               log_print("%6.2f", (float) sum / f);
+       }
+       log_finish();
+       statistics_print_memory_usage();
+       dolog("Number of class loads:    %6d", count_class_loads);
+       dolog("Number of class inits:    %6d", count_class_inits);
+       dolog("Number of loaded Methods: %6d\n", count_all_methods);
+       dolog("Calls of utf_new:                 %6d", count_utf_new);
+       dolog("Calls of utf_new (element found): %6d\n", count_utf_new_found);
+       /* LSRA statistics ********************************************************/
+       dolog("Moves reg -> reg:     %6d", count_mov_reg_reg);
+       dolog("Moves mem -> reg:     %6d", count_mov_mem_reg);
+       dolog("Moves reg -> mem:     %6d", count_mov_reg_mem);
+       dolog("Moves mem -> mem:     %6d", count_mov_mem_mem);
+       dolog("Methods allocated by LSRA:         %6d",
+                 count_methods_allocated_by_lsra);
+       dolog("Conflicts between local Variables: %6d", count_locals_conflicts);
+       dolog("Local Variables held in Memory:    %6d", count_locals_spilled);
+       dolog("Local Variables held in Registers: %6d", count_locals_register);
+       dolog("Stackslots held in Memory:         %6d", count_ss_spilled);
+       dolog("Stackslots held in Registers:      %6d", count_ss_register);
+       dolog("Memory moves at BB Boundaries:     %6d", count_mem_move_bb);
+       dolog("Number of interface slots:         %6d\n", count_interface_size);
+       dolog("Number of Argument stack slots in register:  %6d",
+                 count_argument_reg_ss);
+       dolog("Number of Argument stack slots in memory:    %6d\n",
+                 count_argument_mem_ss);
+       dolog("Number of Methods kept in registers:         %6d\n",
+                 count_method_in_register);
+       /* instruction scheduler statistics ***************************************/
+ #if defined(USE_SCHEDULER)
+       dolog("Instruction scheduler statistics:");
+       dolog("Number of basic blocks:       %7d", count_schedule_basic_blocks);
+       dolog("Number of nodes:              %7d", count_schedule_nodes);
+       dolog("Number of leaders nodes:      %7d", count_schedule_leaders);
+       dolog("Number of max. leaders nodes: %7d", count_schedule_max_leaders);
+       dolog("Length of critical path:      %7d\n", count_schedule_critical_path);
+ #endif
+       /* call statistics ********************************************************/
+       dolog("Function call statistics:");
+       dolog("Number of jni->CallXMethod function invokations: %ld",
+                 count_jni_callXmethod_calls);
+       dolog("Overall number of jni invokations:               %ld",
+                 count_jni_calls);
+       log_println("java-to-native calls:   %10ld", count_calls_java_to_native);
+       log_println("native-to-java calls:   %10ld", count_calls_native_to_java);
+       /* now print other statistics ********************************************/
+ #if defined(ENABLE_INTRP)
+       print_dynamic_super_statistics();
+ #endif
+ }
+ /* statistics_print_date *******************************************************
+    Print current date and time.
+ *******************************************************************************/
+ void statistics_print_date(void)
+ {
+   time_t t;
+   struct tm tm;
+ #if defined(HAVE_TIME)
+   time(&t);
+ #else
+ # error !HAVE_TIME
+ #endif
+ #if defined(HAVE_LOCALTIME_R)
+   localtime_r(&t, &tm);
+ #else
+ # error !HAVE_LOCALTIME_R
+ #endif
+   log_println("%d-%02d-%02d %02d:%02d:%02d",
+                         1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
+                         tm.tm_hour, tm.tm_min, tm.tm_sec);
+ }
+ /* statistics_print_memory_usage ***********************************************
+    Print current memory usage.
+ *******************************************************************************/
+ void statistics_print_memory_usage(void)
+ {
+       s4 sum;
+       log_println("memory usage ----------------------");
+       log_println("");
+       log_println("code:                      %10d", count_code_len);
+       log_println("data:                      %10d", count_data_len);
+       log_println("                            ----------");
+       sum =
+               count_code_len +
+               count_data_len;
+       log_println("                           %10d", sum);
+       log_println("");
+       log_println("classinfo  (%3d B):        %10d", (int) sizeof(classinfo), size_classinfo);
+       log_println("fieldinfo  (%3d B):        %10d", (int) sizeof(fieldinfo), size_fieldinfo);
+       log_println("methodinfo (%3d B):        %10d", (int) sizeof(methodinfo), size_methodinfo);
+       log_println("lineinfo   (%3d B):        %10d", (int) sizeof(lineinfo), size_lineinfo);
+       log_println("codeinfo   (%3d B):        %10d", (int) sizeof(codeinfo), size_codeinfo);
+       log_println("                            ----------");
+       sum =
+               size_classinfo +
+               size_fieldinfo +
+               size_methodinfo +
+               size_lineinfo +
+               size_codeinfo;
+       log_println("                           %10d", sum);
+       log_println("");
+       log_println("linenumber tables (%5d): %10d", count_linenumbertable, size_linenumbertable);
+       log_println("exception tables:          %10d", count_extable_len);
+       log_println("patcher references:        %10d", size_patchref);
++      log_println("cached references:         %10d", size_cachedref);
+       log_println("                            ----------");
+       sum =
+               size_linenumbertable +
+               count_extable_len +
++              size_patchref +
++              size_cachedref;
+       log_println("                           %10d", sum);
+       log_println("");
+       log_println("constant pool:             %10d", count_const_pool_len);
+       log_println("classref:                  %10d", count_classref_len);
+       log_println("parsed descriptors:        %10d", count_parsed_desc_len);
+       log_println("vftbl:                     %10d", count_vftbl_len);
+       log_println("compiler stubs:            %10d", count_cstub_len);
+       log_println("native stubs:              %10d", size_stub_native);
+       log_println("utf:                       %10d", count_utf_len);
+       log_println("vmcode:                    %10d", count_vmcode_len);
+       log_println("stack map:                 %10d", size_stack_map);
+       log_println("string:                    %10d", size_string);
+       log_println("threadobject:              %10d", size_threadobject);
+       log_println("thread index:              %10d", size_thread_index_t);
+       log_println("stack size:                %10d", size_stacksize);
+       log_println("lock record:               %10d", size_lock_record);
+       log_println("lock hashtable:            %10d", size_lock_hashtable);
+       log_println("lock waiter:               %10d", size_lock_waiter);
+       log_println("                            ----------");
+       sum =
+               count_const_pool_len +
+               count_classref_len +
+               count_parsed_desc_len + 
+               count_vftbl_len +
+               count_cstub_len +
+               size_stub_native +
+               count_utf_len +
+               count_vmcode_len +
+               size_stack_map +
+               size_string +
+               size_threadobject +
+               size_thread_index_t +
+               size_stacksize +
+               size_lock_record +
+               size_lock_hashtable +
+               size_lock_waiter;
+       log_println("                           %10d", sum);
+       log_println("");
+       log_println("max. code memory:          %10d", maxcodememusage);
+       log_println("max. heap memory:          %10d", maxmemusage);
+       log_println("max. dump memory:          %10d", maxdumpsize);
+       log_println("");
+       log_println("heap memory not freed:     %10d", (int32_t) memoryusage);
+       log_println("dump memory not freed:     %10d", (int32_t) globalallocateddumpsize);
+       log_println("");
+ }
+ /* statistics_print_gc_memory_usage ********************************************
+    Print current GC memory usage.
+ *******************************************************************************/
+ void statistics_print_gc_memory_usage(void)
+ {
+       static int64_t count = 0;
+       int64_t max;
+       int64_t size;
+       int64_t free;
+       int64_t used;
+       int64_t total;
+       count++;
+       max   = gc_get_max_heap_size();
+       size  = gc_get_heap_size();
+       free  = gc_get_free_bytes();
+       used  = size - free;
+       total = gc_get_total_bytes();
+       if (opt_ProfileMemoryUsageGNUPlot) {
+               if (count == 1)
+                       fprintf(opt_ProfileMemoryUsageGNUPlot, "plot \"profile.dat\" using 1:2 with lines title \"max. Java heap size\", \"profile.dat\" using 1:3 with lines title \"Java heap size\", \"profile.dat\" using 1:4 with lines title \"used\", \"profile.dat\" using 1:5 with lines title \"free\"\n");
+ #if SIZEOF_VOID_P == 8
+               fprintf(opt_ProfileMemoryUsageGNUPlot, "%ld %ld %ld %ld %ld\n", count, max, size, used, free);
+ #else
+               fprintf(opt_ProfileMemoryUsageGNUPlot, "%lld %lld %lld %lld %lld\n", count, max, size, used, free);
+ #endif
+               fflush(opt_ProfileMemoryUsageGNUPlot);
+       }
+       else {
+               log_println("GC memory usage -------------------");
+               log_println("");
+               log_println("max. Java heap size: %10lld", max);
+               log_println("");
+               log_println("Java heap size:      %10lld", size);
+               log_println("used:                %10lld", used);
+               log_println("free:                %10lld", free);
+               log_println("totally used:        %10lld", total);
+               log_println("");
+       }
+ }
+ /*
+  * These are local overrides for various environment variables in Emacs.
+  * Please do not remove this and leave it at the end of the file, where
+  * Emacs will automagically detect them.
+  * ---------------------------------------------------------------------
+  * Local variables:
+  * mode: c
+  * indent-tabs-mode: t
+  * c-basic-offset: 4
+  * tab-width: 4
+  * End:
+  * vim:noexpandtab:sw=4:ts=4:
+  */
index 0000000000000000000000000000000000000000,15142d00d7f3197c8d310464041a5b691cd98898..46bebed985232e50a1586295cc1d4743ab5b9870
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,266 +1,268 @@@
+ /* src/vm/statistics.h - exports global varables for statistics
+    Copyright (C) 1996-2005, 2006, 2007, 2008
+    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+    This file is part of CACAO.
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2, or (at
+    your option) any later version.
+    This program is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+    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., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+ */
+ #ifndef _STATISTICS_H
+ #define _STATISTICS_H
+ #include "config.h"
+ #include <stdint.h>
+ #include "vm/types.h"
+ #include "vm/global.h"
+ /* statistic macros ***********************************************************/
+ #if defined(ENABLE_STATISTICS)
+ #define STATISTICS(x) \
+     do { \
+         if (opt_stat) { \
+             x; \
+         } \
+     } while (0)
+ #else
+ #define STATISTICS(x)    /* nothing */
+ #endif
+ /* in_  inline statistics */
+ #define IN_MAX                  9
+ #define IN_UNIQUEVIRT           0x0000 
+ #define IN_UNIQUE_INTERFACE     0x0001
+ #define IN_OUTSIDERS            0x0004
+ #define IN_MAXDEPTH             0x0008
+ #define IN_MAXCODE              0x0010
+ #define IN_JCODELENGTH          0x0020
+ #define IN_EXCEPTION            0x0040
+ #define IN_NOT_UNIQUE_VIRT      0x0080
+ #define IN_NOT_UNIQUE_INTERFACE 0x0100
+ #define N_UNIQUEVIRT            0
+ #define N_UNIQUE_INTERFACE      1
+ #define N_OUTSIDERS             2
+ #define N_MAXDEPTH            3       
+ #define N_MAXCODE               4 
+ #define N_JCODELENGTH           5 
+ #define N_EXCEPTION            6 
+ #define N_NOT_UNIQUE_VIRT       7 
+ #define N_NOT_UNIQUE_INTERFACE  8 
+ /* global variables ***********************************************************/
+ extern s4 codememusage;
+ extern s4 maxcodememusage;
+ extern s4 memoryusage;
+ extern s4 maxmemusage;
+ extern s4 maxdumpsize;
+ extern s4 globalallocateddumpsize;
+ extern s4 globaluseddumpsize;
+ /* variables for measurements *************************************************/
+ extern s4 size_classinfo;
+ extern s4 size_fieldinfo;
+ extern s4 size_methodinfo;
+ extern s4 size_lineinfo;
+ extern s4 size_codeinfo;
+ extern s4 size_stub_native;
+ extern s4 size_stack_map;
+ extern s4 size_string;
+ extern s4 size_threadobject;
+ extern int32_t size_thread_index_t;
+ extern int32_t size_stacksize;
+ extern s4 size_lock_record;
+ extern s4 size_lock_hashtable;
+ extern s4 size_lock_waiter;
+ extern int32_t count_linenumbertable;
+ extern int32_t size_linenumbertable;
+ extern s4 size_patchref;
++extern s4 size_cachedref;
++
+ extern u8 count_calls_java_to_native;
+ extern u8 count_calls_native_to_java;
+ extern int count_const_pool_len;
+ extern int count_classref_len;
+ extern int count_parsed_desc_len;
+ extern int count_vftbl_len;
+ extern int count_all_methods;
+ extern int count_methods_marked_used;  /*RTA*/
+ extern int count_vmcode_len;
+ extern int count_extable_len;
+ extern int count_class_loads;
+ extern int count_class_inits;
+ extern int count_utf_len;               /* size of utf hash                   */
+ extern int count_utf_new;
+ extern int count_utf_new_found;
+ extern int count_locals_conflicts;
+ extern int count_locals_spilled;
+ extern int count_locals_register;
+ extern int count_ss_spilled;
+ extern int count_ss_register;
+ extern int count_methods_allocated_by_lsra;
+ extern int count_mem_move_bb;
+ extern int count_interface_size;
+ extern int count_argument_mem_ss;
+ extern int count_argument_reg_ss;
+ extern int count_method_in_register;
+ extern int count_mov_reg_reg;
+ extern int count_mov_mem_reg;
+ extern int count_mov_reg_mem;
+ extern int count_mov_mem_mem;
+ extern int count_jit_calls;
+ extern int count_methods;
+ extern int count_spills_read_ila;
+ extern int count_spills_read_flt;
+ extern int count_spills_read_dbl;
+ extern int count_spills_write_ila;
+ extern int count_spills_write_flt;
+ extern int count_spills_write_dbl;
+ extern int count_pcmd_activ;
+ extern int count_pcmd_drop;
+ extern int count_pcmd_zero;
+ extern int count_pcmd_const_store;
+ extern int count_pcmd_const_alu;
+ extern int count_pcmd_const_bra;
+ extern int count_pcmd_load;
+ extern int count_pcmd_move;
+ extern int count_load_instruction;
+ extern int count_pcmd_store;
+ extern int count_pcmd_store_comb;
+ extern int count_dup_instruction;
+ extern int count_pcmd_op;
+ extern int count_pcmd_mem;
+ extern int count_pcmd_met;
+ extern int count_pcmd_bra;
+ extern int count_pcmd_table;
+ extern int count_pcmd_return;
+ extern int count_pcmd_returnx;
+ extern int count_check_null;
+ extern int count_check_bound;
+ extern int count_max_basic_blocks;
+ extern int count_basic_blocks;
+ extern int count_max_javainstr;
+ extern int count_javainstr;
+ extern int count_javacodesize;
+ extern int count_javaexcsize;
+ extern int count_calls;
+ extern int count_tryblocks;
+ extern int count_code_len;
+ extern int count_data_len;
+ extern int count_cstub_len;
+ extern int count_max_new_stack;
+ extern int count_upper_bound_new_stack;
+ extern int count_emit_branch;
+ extern int count_emit_branch_8bit;
+ extern int count_emit_branch_16bit;
+ extern int count_emit_branch_32bit;
+ extern int count_emit_branch_64bit;
+ extern s4 count_branches_resolved;
+ extern s4 count_branches_unresolved;
+ extern int *count_block_stack;
+ extern int *count_analyse_iterations;
+ extern int *count_method_bb_distribution;
+ extern int *count_block_size_distribution;
+ extern int *count_store_length;
+ extern int *count_store_depth;
+                                 /* in_  inline statistics */
+ extern int count_in;
+ extern int count_in_uniqVirt;
+ extern int count_in_uniqIntf;
+ extern int count_in_rejected;
+ extern int count_in_rejected_mult;
+ extern int count_in_outsiders;
+ extern int count_in_uniqueVirt_not_inlined;
+ extern int count_in_uniqueInterface_not_inlined;
+ extern int count_in_maxDepth;
+ extern int count_in_maxMethods;
+ extern u2 count_in_not   [512];
+ /* instruction scheduler statistics *******************************************/
+ extern s4 count_schedule_basic_blocks;
+ extern s4 count_schedule_nodes;
+ extern s4 count_schedule_leaders;
+ extern s4 count_schedule_max_leaders;
+ extern s4 count_schedule_critical_path;
+ /* function prototypes ********************************************************/
+ s8 getcputime(void);
+ void loadingtime_start(void);
+ void loadingtime_stop(void);
+ void compilingtime_start(void);
+ void compilingtime_stop(void);
+ void print_times(void);
+ void print_stats(void);
+ void statistics_print_date(void);
+ void statistics_print_memory_usage(void);
+ void statistics_print_gc_memory_usage(void);
+ void mem_usagelog(bool givewarnings);
+ void compiledinvokation(void);
+ void jnicallXmethodnvokation(void);
+ void jniinvokation(void);
+ #endif /* _STATISTICS_H */
+ /*
+  * These are local overrides for various environment variables in Emacs.
+  * Please do not remove this and leave it at the end of the file, where
+  * Emacs will automagically detect them.
+  * ---------------------------------------------------------------------
+  * Local variables:
+  * mode: c
+  * indent-tabs-mode: t
+  * c-basic-offset: 4
+  * tab-width: 4
+  * End:
+  */
diff --cc src/vm/vm.cpp
index 0000000000000000000000000000000000000000,cfe607a68a1931a1163d0377def097379d0b00ff..0f099b7c9e7ebe002d85f84e15275f75c03bac2e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,2679 +1,2684 @@@
+ /* src/vm/vm.cpp - VM startup and shutdown functions
+    Copyright (C) 1996-2005, 2006, 2007, 2008
+    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+    This file is part of CACAO.
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2, or (at
+    your option) any later version.
+    This program is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+    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., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+ */
+ #include "config.h"
+ #include <stdint.h>
+ #include <exception>
+ #include <assert.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include "vm/types.h"
+ #include "arch.h"
+ #include "md-abi.h"
+ #include "vm/jit/abi-asm.h"
+ #include "mm/codememory.h"
+ #include "mm/gc.hpp"
+ #include "mm/memory.h"
+ #include "native/jni.h"
+ #include "native/llni.h"
+ #include "native/localref.h"
+ #include "native/native.h"
+ #include "native/vm/nativevm.h"
+ #include "threads/lock-common.h"
+ #include "threads/threadlist.h"
+ #include "threads/thread.hpp"
+ #include "toolbox/logging.h"
+ #include "vm/array.h"
+ #if defined(ENABLE_ASSERTION)
+ #include "vm/assertion.h"
+ #endif
+ #include "vm/builtin.h"
+ #include "vm/classcache.h"
+ #include "vm/exceptions.hpp"
+ #include "vm/finalizer.h"
+ #include "vm/global.h"
+ #include "vm/globals.hpp"
+ #include "vm/initialize.h"
+ #include "vm/options.h"
+ #include "vm/os.hpp"
+ #include "vm/package.hpp"
+ #include "vm/primitive.hpp"
+ #include "vm/properties.h"
+ #include "vm/signallocal.h"
+ #include "vm/statistics.h"
+ #include "vm/string.hpp"
+ #include "vm/suck.h"
+ #include "vm/vm.hpp"
+ #include "vm/jit/argument.h"
+ #include "vm/jit/asmpart.h"
+ #include "vm/jit/code.h"
+ #if defined(ENABLE_DISASSEMBLER)
+ # include "vm/jit/disass.h"
+ #endif
+ #include "vm/jit/jit.h"
++#include "vm/jit/jitcache.h"
+ #include "vm/jit/methodtree.h"
+ #if defined(ENABLE_PROFILING)
+ # include "vm/jit/optimizing/profile.h"
+ #endif
+ #include "vm/jit/optimizing/recompile.h"
+ #if defined(ENABLE_PYTHON)
+ # include "vm/jit/python.h"
+ #endif
+ #include "vm/jit/trap.h"
+ #if defined(ENABLE_JVMTI)
+ # include "native/jvmti/cacaodbg.h"
+ #endif
+ #if defined(ENABLE_VMLOG)
+ #include <vmlog_cacao.h>
+ #endif
+ /**
+  * This is _the_ instance of the VM.
+  */
+ VM* vm;
+ /* global variables ***********************************************************/
+ s4 vms = 0;                             /* number of VMs created              */
+ static classinfo *mainclass = NULL;
+ #if defined(ENABLE_INTRP)
+ u1 *intrp_main_stack = NULL;
+ #endif
+ /* define heap sizes **********************************************************/
+ #define HEAP_MAXSIZE      128 * 1024 * 1024 /* default 128MB                  */
+ #define HEAP_STARTSIZE      2 * 1024 * 1024 /* default 2MB                    */
+ #define STACK_SIZE               128 * 1024 /* default 64kB                   */
+ /* define command line options ************************************************/
+ enum {
+       OPT_FOO,
+       /* Java options */
+       OPT_JAR,
+       OPT_D32,
+       OPT_D64,
+       OPT_CLASSPATH,
+       OPT_D,
+       OPT_VERBOSE,
+       OPT_VERSION,
+       OPT_SHOWVERSION,
+       OPT_FULLVERSION,
+       OPT_HELP,
+       OPT_X,
+       OPT_XX,
+       OPT_EA,
+       OPT_DA,
+       OPT_EA_NOARG,
+       OPT_DA_NOARG,
+     
+       OPT_ESA,
+       OPT_DSA,
+       /* Java non-standard options */
+       OPT_JIT,
+       OPT_INTRP,
+       OPT_BOOTCLASSPATH,
+       OPT_BOOTCLASSPATH_A,
+       OPT_BOOTCLASSPATH_P,
+       OPT_BOOTCLASSPATH_C,
+ #if defined(ENABLE_PROFILING)
+       OPT_PROF,
+       OPT_PROF_OPTION,
+ #endif
+       OPT_MS,
+       OPT_MX,
+       /* CACAO options */
+       OPT_VERBOSE1,
+       OPT_NOIEEE,
+ #if defined(ENABLE_STATISTICS)
+       OPT_TIME,
+       OPT_STAT,
+ #endif
+       OPT_LOG,
+       OPT_CHECK,
+       OPT_LOAD,
+       OPT_SHOW,
+       OPT_DEBUGCOLOR,
+ #if !defined(NDEBUG)
+       OPT_ALL,
+       OPT_METHOD,
+       OPT_SIGNATURE,
+ #endif
+ #if defined(ENABLE_VERIFIER)
+       OPT_NOVERIFY,
+ #if defined(TYPECHECK_VERBOSE)
+       OPT_VERBOSETC,
+ #endif
+ #endif /* defined(ENABLE_VERIFIER) */
+       /* optimization options */
+ #if defined(ENABLE_LOOP)
+       OPT_OLOOP,
+ #endif
+       
+ #if defined(ENABLE_IFCONV)
+       OPT_IFCONV,
+ #endif
+ #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+       OPT_LSRA,
+ #endif
+ #if defined(ENABLE_INTRP)
+       /* interpreter options */
+       OPT_NO_DYNAMIC,
+       OPT_NO_REPLICATION,
+       OPT_NO_QUICKSUPER,
+       OPT_STATIC_SUPERS,
+       OPT_TRACE,
+ #endif
+       OPT_SS,
+ #ifdef ENABLE_JVMTI
+       OPT_DEBUG,
+       OPT_XRUNJDWP,
+       OPT_NOAGENT,
+       OPT_AGENTLIB,
+       OPT_AGENTPATH,
+ #endif
+ #if defined(ENABLE_DEBUG_FILTER)
+       OPT_FILTER_VERBOSECALL_INCLUDE,
+       OPT_FILTER_VERBOSECALL_EXCLUDE,
+       OPT_FILTER_SHOW_METHOD,
+ #endif
+       DUMMY
+ };
+ opt_struct opts[] = {
+       { "foo",               false, OPT_FOO },
+       /* Java options */
+       { "jar",               false, OPT_JAR },
+       { "d32",               false, OPT_D32 },
+       { "d64",               false, OPT_D64 },
+       { "client",            false, OPT_IGNORE },
+       { "server",            false, OPT_IGNORE },
+       { "jvm",               false, OPT_IGNORE },
+       { "hotspot",           false, OPT_IGNORE },
+       { "classpath",         true,  OPT_CLASSPATH },
+       { "cp",                true,  OPT_CLASSPATH },
+       { "D",                 true,  OPT_D },
+       { "version",           false, OPT_VERSION },
+       { "showversion",       false, OPT_SHOWVERSION },
+       { "fullversion",       false, OPT_FULLVERSION },
+       { "help",              false, OPT_HELP },
+       { "?",                 false, OPT_HELP },
+       { "X",                 false, OPT_X },
+       { "XX:",               true,  OPT_XX },
+       { "ea:",               true,  OPT_EA },
+       { "da:",               true,  OPT_DA },
+       { "ea",                false, OPT_EA_NOARG },
+       { "da",                false, OPT_DA_NOARG },
+       { "enableassertions:",  true,  OPT_EA },
+       { "disableassertions:", true,  OPT_DA },
+       { "enableassertions",   false, OPT_EA_NOARG },
+       { "disableassertions",  false, OPT_DA_NOARG },
+       { "esa",                     false, OPT_ESA },
+       { "enablesystemassertions",  false, OPT_ESA },
+       { "dsa",                     false, OPT_DSA },
+       { "disablesystemassertions", false, OPT_DSA },
+       { "noasyncgc",         false, OPT_IGNORE },
+ #if defined(ENABLE_VERIFIER)
+       { "noverify",          false, OPT_NOVERIFY },
+       { "Xverify:none",      false, OPT_NOVERIFY },
+ #endif
+       { "v",                 false, OPT_VERBOSE1 },
+       { "verbose:",          true,  OPT_VERBOSE },
+ #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
+       { "verbosetc",         false, OPT_VERBOSETC },
+ #endif
+ #if defined(__ALPHA__)
+       { "noieee",            false, OPT_NOIEEE },
+ #endif
+ #if defined(ENABLE_STATISTICS)
+       { "time",              false, OPT_TIME },
+       { "stat",              false, OPT_STAT },
+ #endif
+       { "log",               true,  OPT_LOG },
+       { "c",                 true,  OPT_CHECK },
+       { "l",                 false, OPT_LOAD },
+ #if !defined(NDEBUG)
+       { "all",               false, OPT_ALL },
+       { "sig",               true,  OPT_SIGNATURE },
+ #endif
+ #if defined(ENABLE_LOOP)
+       { "oloop",             false, OPT_OLOOP },
+ #endif
+ #if defined(ENABLE_IFCONV)
+       { "ifconv",            false, OPT_IFCONV },
+ #endif
+ #if defined(ENABLE_LSRA)
+       { "lsra",              false, OPT_LSRA },
+ #endif
+ #if  defined(ENABLE_SSA)
+       { "lsra",              true, OPT_LSRA },
+ #endif
+ #if defined(ENABLE_INTRP)
+       /* interpreter options */
+       { "trace",             false, OPT_TRACE },
+       { "static-supers",     true,  OPT_STATIC_SUPERS },
+       { "no-dynamic",        false, OPT_NO_DYNAMIC },
+       { "no-replication",    false, OPT_NO_REPLICATION },
+       { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
+ #endif
+       /* JVMTI Agent Command Line Options */
+ #ifdef ENABLE_JVMTI
+       { "agentlib:",         true,  OPT_AGENTLIB },
+       { "agentpath:",        true,  OPT_AGENTPATH },
+ #endif
+       /* Java non-standard options */
+       { "Xjit",              false, OPT_JIT },
+       { "Xint",              false, OPT_INTRP },
+       { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
+       { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
+       { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
+       { "Xbootclasspath/c:", true,  OPT_BOOTCLASSPATH_C },
+ #ifdef ENABLE_JVMTI
+       { "Xdebug",            false, OPT_DEBUG },
+       { "Xnoagent",          false, OPT_NOAGENT },
+       { "Xrunjdwp",          true,  OPT_XRUNJDWP },
+ #endif 
+       { "Xms",               true,  OPT_MS },
+       { "ms",                true,  OPT_MS },
+       { "Xmx",               true,  OPT_MX },
+       { "mx",                true,  OPT_MX },
+       { "Xss",               true,  OPT_SS },
+       { "ss",                true,  OPT_SS },
+ #if defined(ENABLE_PROFILING)
+       { "Xprof:",            true,  OPT_PROF_OPTION },
+       { "Xprof",             false, OPT_PROF },
+ #endif
+       /* keep these at the end of the list */
+ #if !defined(NDEBUG)
+       { "m",                 true,  OPT_METHOD },
+ #endif
+       { "s",                 true,  OPT_SHOW },
+       { "debug-color",      false,  OPT_DEBUGCOLOR },
+ #if defined(ENABLE_DEBUG_FILTER)
+       { "XXfi",              true,  OPT_FILTER_VERBOSECALL_INCLUDE },
+       { "XXfx",              true,  OPT_FILTER_VERBOSECALL_EXCLUDE },
+       { "XXfm",              true,  OPT_FILTER_SHOW_METHOD },
+ #endif
+       { NULL,                false, 0 }
+ };
+ /* usage ***********************************************************************
+    Prints the correct usage syntax to stdout.
+ *******************************************************************************/
+ void usage(void)
+ {
+       puts("Usage: cacao [-options] classname [arguments]");
+       puts("               (to run a class file)");
+       puts("   or  cacao [-options] -jar jarfile [arguments]");
+       puts("               (to run a standalone jar file)\n");
+       puts("where options include:");
+       puts("    -d32                     use 32-bit data model if available");
+       puts("    -d64                     use 64-bit data model if available");
+       puts("    -client                  compatibility (currently ignored)");
+       puts("    -server                  compatibility (currently ignored)");
+       puts("    -jvm                     compatibility (currently ignored)");
+       puts("    -hotspot                 compatibility (currently ignored)\n");
+       puts("    -cp <path>               specify a path to look for classes");
+       puts("    -classpath <path>        specify a path to look for classes");
+       puts("    -D<name>=<value>         add an entry to the property list");
+       puts("    -verbose[:class|gc|jni]  enable specific verbose output");
+       puts("    -version                 print product version and exit");
+       puts("    -fullversion             print jpackage-compatible product version and exit");
+       puts("    -showversion             print product version and continue");
+       puts("    -help, -?                print this help message");
+       puts("    -X                       print help on non-standard Java options");
+       puts("    -XX                      print help on debugging options");
+     puts("    -ea[:<packagename>...|:<classname>]");
+     puts("    -enableassertions[:<packagename>...|:<classname>]");
+       puts("                             enable assertions with specified granularity");
+       puts("    -da[:<packagename>...|:<classname>]");
+       puts("    -disableassertions[:<packagename>...|:<classname>]");
+       puts("                             disable assertions with specified granularity");
+       puts("    -esa | -enablesystemassertions");
+       puts("                             enable system assertions");
+       puts("    -dsa | -disablesystemassertions");
+       puts("                             disable system assertions");
+ #ifdef ENABLE_JVMTI
+       puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
+       puts ("                                         for jdwp help use: -agentlib:jdwp=help");
+       puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
+ #endif
+       /* exit with error code */
+       exit(1);
+ }   
+ static void Xusage(void)
+ {
+ #if defined(ENABLE_JIT)
+       puts("    -Xjit                    JIT mode execution (default)");
+ #endif
+ #if defined(ENABLE_INTRP)
+       puts("    -Xint                    interpreter mode execution");
+ #endif
+       puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
+     puts("                             value is set as bootstrap class path");
+       puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
+       puts("                             value is appended to the bootstrap class path");
+       puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
+       puts("                             value is prepended to the bootstrap class path");
+       puts("    -Xbootclasspath/c:<zip/jar files and directories separated by :>");
+       puts("                             value is used as Java core library, but the");
+       puts("                             hardcoded VM interface classes are prepended");
+       printf("    -Xms<size>               set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
+       printf("    -Xmx<size>               set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
+       printf("    -Xss<size>               set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
+ #if defined(ENABLE_PROFILING)
+       puts("    -Xprof[:bb]              collect and print profiling data");
+ #endif
+ #if defined(ENABLE_JVMTI)
+     /* -Xdebug option depend on gnu classpath JDWP options. options: 
+        transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
+       puts("    -Xdebug                  enable remote debugging\n");
+       puts("    -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
+       puts("                             enable remote debugging\n");
+ #endif 
+       /* exit with error code */
+       exit(1);
+ }   
+ #if 0
+ static void XXusage(void)
+ {
+       puts("    -v                       write state-information");
+ #if !defined(NDEBUG)
+       puts("    -verbose:jit             enable specific verbose output");
+       puts("    -debug-color             colored output for ANSI terms");
+ #endif
+ #ifdef TYPECHECK_VERBOSE
+       puts("    -verbosetc               write debug messages while typechecking");
+ #endif
+ #if defined(__ALPHA__)
+       puts("    -noieee                  don't use ieee compliant arithmetic");
+ #endif
+ #if defined(ENABLE_VERIFIER)
+       puts("    -noverify                don't verify classfiles");
+ #endif
+ #if defined(ENABLE_STATISTICS)
+       puts("    -time                    measure the runtime");
+       puts("    -stat                    detailed compiler statistics");
+ #endif
+       puts("    -log logfile             specify a name for the logfile");
+       puts("    -c(heck)b(ounds)         don't check array bounds");
+       puts("            s(ync)           don't check for synchronization");
+ #if defined(ENABLE_LOOP)
+       puts("    -oloop                   optimize array accesses in loops");
+ #endif
+       puts("    -l                       don't start the class after loading");
+ #if !defined(NDEBUG)
+       puts("    -all                     compile all methods, no execution");
+       puts("    -m                       compile only a specific method");
+       puts("    -sig                     specify signature for a specific method");
+ #endif
+       puts("    -s...                    show...");
+       puts("      (c)onstants            the constant pool");
+       puts("      (m)ethods              class fields and methods");
+       puts("      (u)tf                  the utf - hash");
+       puts("      (i)ntermediate         intermediate representation");
+ #if defined(ENABLE_DISASSEMBLER)
+       puts("      (a)ssembler            disassembled listing");
+       puts("      n(o)ps                 show NOPs in disassembler output");
+ #endif
+       puts("      (d)atasegment          data segment listing");
+ #if defined(ENABLE_IFCONV)
+       puts("    -ifconv                  use if-conversion");
+ #endif
+ #if defined(ENABLE_LSRA)
+       puts("    -lsra                    use linear scan register allocation");
+ #endif
+ #if defined(ENABLE_SSA)
+       puts("    -lsra:...                use linear scan register allocation (with SSA)");
+       puts("       (d)ead code elimination");
+       puts("       (c)opy propagation");
+ #endif
+ #if defined(ENABLE_DEBUG_FILTER)
+       puts("    -XXfi <regex>            begin of dynamic scope for verbosecall filter");
+       puts("    -XXfx <regex>            end of dynamic scope for verbosecall filter");
+       puts("    -XXfm <regex>            filter for show options");
+ #endif
+       /* exit with error code */
+       exit(1);
+ }
+ #endif
+ /* version *********************************************************************
+    Only prints cacao version information.
+ *******************************************************************************/
+ static void version(bool opt_exit)
+ {
+       puts("java version \""JAVA_VERSION"\"");
+       puts("CACAO version "VERSION"\n");
+       puts("Copyright (C) 1996-2005, 2006, 2007, 2008");
+       puts("CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO");
+       puts("This is free software; see the source for copying conditions.  There is NO");
+       puts("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
+       /* exit normally, if requested */
+       if (opt_exit)
+               exit(0);
+ }
+ /* fullversion *****************************************************************
+    Prints a Sun compatible version information (required e.g. by
+    jpackage, www.jpackage.org).
+ *******************************************************************************/
+ static void fullversion(void)
+ {
+       puts("java full version \"cacao-"JAVA_VERSION"\"");
+       /* exit normally */
+       exit(0);
+ }
+ static void vm_printconfig(void)
+ {
+       puts("Configure/Build options:\n");
+       puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
+ #if defined(__VERSION__)
+       puts("  CC         : "VERSION_CC" ("__VERSION__")");
+ #else
+       puts("  CC         : "VERSION_CC"");
+ #endif
+       puts("  CFLAGS     : "VERSION_CFLAGS"\n");
+       puts("Default variables:\n");
+       printf("  maximum heap size              : %d\n", HEAP_MAXSIZE);
+       printf("  initial heap size              : %d\n", HEAP_STARTSIZE);
+       printf("  stack size                     : %d\n", STACK_SIZE);
+ #if defined(ENABLE_JRE_LAYOUT)
+       /* When we're building with JRE-layout, the default paths are the
+          same as the runtime paths. */
+ #else
+ # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       puts("  gnu.classpath.boot.library.path: "JAVA_RUNTIME_LIBRARY_LIBDIR);
+       puts("  java.boot.class.path           : "CACAO_VM_ZIP":"JAVA_RUNTIME_LIBRARY_CLASSES"");
+ # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       puts("  sun.boot.library.path          : "JAVA_RUNTIME_LIBRARY_LIBDIR);
+       puts("  java.boot.class.path           : "JAVA_RUNTIME_LIBRARY_CLASSES);
+ # endif
+ #endif
+       puts("");
+       puts("Runtime variables:\n");
+       printf("  maximum heap size              : %d\n", opt_heapmaxsize);
+       printf("  initial heap size              : %d\n", opt_heapstartsize);
+       printf("  stack size                     : %d\n", opt_stacksize);
+ #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       printf("  gnu.classpath.boot.library.path: %s\n", properties_get("gnu.classpath.boot.library.path"));
+ #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       printf("  sun.boot.library.path          : %s\n", properties_get("sun.boot.library.path"));
+ #endif
+       printf("  java.boot.class.path           : %s\n", properties_get("java.boot.class.path"));
+       printf("  java.class.path                : %s\n", properties_get("java.class.path"));
+ }
+ /* forward declarations *******************************************************/
+ static char *vm_get_mainclass_from_jar(char *mainstring);
+ #if !defined(NDEBUG)
+ static void  vm_compile_all(void);
+ static void  vm_compile_method(char* mainname);
+ #endif
+ /**
+  * Implementation for JNI_CreateJavaVM.  This function creates a VM
+  * object.
+  *
+  * @param p_vm
+  * @param p_env
+  * @param vm_args
+  *
+  * @return true on success, false otherwise.
+  */
+ bool VM::create(JavaVM** p_vm, void** p_env, void* vm_args)
+ {
+       JavaVMInitArgs* _vm_args;
+       // Get the arguments for the new JVM.
+       _vm_args = (JavaVMInitArgs *) vm_args;
+       // Instantiate a new VM.
+       try {
+               vm = new VM(_vm_args);
+       }
+       catch (std::exception e) {
+               // FIXME How can we delete the resources allocated?
+ //            /* release allocated memory */
+ //            FREE(env, _Jv_JNIEnv);
+ //            FREE(vm, _Jv_JavaVM);
+               vm = NULL;
+               return false;
+       }
+       // Return the values.
+       *p_vm  = vm->get_javavm();
+       *p_env = vm->get_jnienv();
+       return true;
+ }
+ /**
+  * C wrapper for VM::create.
+  */
+ extern "C" {
+       bool VM_create(JavaVM** p_vm, void** p_env, void* vm_args)
+       {
+               return VM::create(p_vm, p_env, vm_args);
+       }
+ }
+ /**
+  * VM constructor.
+  */
+ VM::VM(JavaVMInitArgs* vm_args)
+ {
+       // Very first thing to do: we are initializing.
+       _initializing = true;
+       // Make ourself globally visible.
+       // XXX Is this a good idea?
+       vm = this;
+       /* create and fill a JavaVM structure */
+       _javavm = new JavaVM();
+ #if defined(ENABLE_JNI)
+       _javavm->functions = &_Jv_JNIInvokeInterface;
+ #endif
+       /* get the VM and Env tables (must be set before vm_create) */
+       /* XXX JVMTI Agents needs a JavaVM  */
+       _jnienv = new JNIEnv();
+ #if defined(ENABLE_JNI)
+       _jnienv->functions = &_Jv_JNINativeInterface;
+ #endif
+       /* actually create the JVM */
+       int   len;
+       char *p;
+       char *boot_class_path;
+       char *class_path;
+       int   opt;
+       bool  opt_version;
+       bool  opt_exit;
+ #if defined(ENABLE_JVMTI)
+       lt_dlhandle  handle;
+       char *libname, *agentarg;
+       bool jdwp,agentbypath;
+       jdwp = agentbypath = false;
+ #endif
+ #if defined(ENABLE_JNI)
+       /* Check the JNI version requested. */
+       if (!jni_version_check(vm_args->version))
+               throw std::exception();
+ #endif
+       /* We only support 1 JVM instance. */
+       if (vms > 0)
+               throw std::exception();
+       /* Install the exit handler. */
+       if (atexit(vm_exit_handler))
+               vm_abort("atexit failed: %s\n", strerror(errno));
+       /* Set some options. */
+       opt_version       = false;
+       opt_exit          = false;
+       opt_noieee        = false;
+       opt_heapmaxsize   = HEAP_MAXSIZE;
+       opt_heapstartsize = HEAP_STARTSIZE;
+       opt_stacksize     = STACK_SIZE;
+       /* Initialize the properties list before command-line handling.
+          Otherwise -XX:+PrintConfig crashes. */
+       properties_init();
+       /* First of all, parse the -XX options. */
+ #if defined(ENABLE_VMLOG)
+       vmlog_cacao_init_options();
+ #endif
+       options_xx(vm_args);
+ #if defined(ENABLE_VMLOG)
+       vmlog_cacao_init();
+ #endif
+       /* We need to check if the actual size of a java.lang.Class object
+          is smaller or equal than the assumption made in
+          src/vm/class.h. */
+ #warning FIXME We need to check the size of java.lang.Class!!!
+ //    if (sizeof(java_lang_Class) > sizeof(dummy_java_lang_Class))
+ //            vm_abort("vm_create: java_lang_Class structure is bigger than classinfo.object (%d > %d)", sizeof(java_lang_Class), sizeof(dummy_java_lang_Class));
+       /* set the VM starttime */
+       _starttime = builtin_currenttimemillis();
+ #if defined(ENABLE_JVMTI)
+       /* initialize JVMTI related  **********************************************/
+       jvmti = false;
+ #endif
+       /* Fill the properties before command-line handling. */
+       properties_set();
+       /* iterate over all passed options */
+       while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
+               switch (opt) {
+               case OPT_FOO:
+                       opt_foo = true;
+                       break;
+               case OPT_IGNORE:
+                       break;
+                       
+               case OPT_JAR:
+                       opt_jar = true;
+                       break;
+               case OPT_D32:
+ #if SIZEOF_VOID_P == 8
+                       puts("Running a 32-bit JVM is not supported on this platform.");
+                       exit(1);
+ #endif
+                       break;
+               case OPT_D64:
+ #if SIZEOF_VOID_P == 4
+                       puts("Running a 64-bit JVM is not supported on this platform.");
+                       exit(1);
+ #endif
+                       break;
+               case OPT_CLASSPATH:
+                       /* Forget old classpath and set the argument as new
+                          classpath. */
+                       // FIXME Make class_path const char*.
+                       class_path = (char*) properties_get("java.class.path");
+                       p = MNEW(char, strlen(opt_arg) + strlen("0"));
+                       strcpy(p, opt_arg);
+ #if defined(ENABLE_JAVASE)
+                       properties_add("java.class.path", p);
+ #endif
+                       MFREE(class_path, char, strlen(class_path));
+                       break;
+               case OPT_D:
+                       for (unsigned int i = 0; i < strlen(opt_arg); i++) {
+                               if (opt_arg[i] == '=') {
+                                       opt_arg[i] = '\0';
+                                       properties_add(opt_arg, opt_arg + i + 1);
+                                       goto opt_d_done;
+                               }
+                       }
+                       /* if no '=' is given, just create an empty property */
+                       properties_add(opt_arg, "");
+               opt_d_done:
+                       break;
+               case OPT_BOOTCLASSPATH:
+                       /* Forget default bootclasspath and set the argument as
+                          new boot classpath. */
+                       // FIXME Make boot_class_path const char*.
+                       boot_class_path = (char*) properties_get("sun.boot.class.path");
+                       p = MNEW(char, strlen(opt_arg) + strlen("0"));
+                       strcpy(p, opt_arg);
+                       properties_add("sun.boot.class.path", p);
+                       properties_add("java.boot.class.path", p);
+                       MFREE(boot_class_path, char, strlen(boot_class_path));
+                       break;
+               case OPT_BOOTCLASSPATH_A:
+                       /* Append to bootclasspath. */
+                       // FIXME Make boot_class_path const char*.
+                       boot_class_path = (char*) properties_get("sun.boot.class.path");
+                       len = strlen(boot_class_path);
+                       // XXX (char*) quick hack
+                       p = (char*) MREALLOC(boot_class_path,
+                                                char,
+                                                len + strlen("0"),
+                                                len + strlen(":") +
+                                                strlen(opt_arg) + strlen("0"));
+                       strcat(p, ":");
+                       strcat(p, opt_arg);
+                       properties_add("sun.boot.class.path", p);
+                       properties_add("java.boot.class.path", p);
+                       break;
+               case OPT_BOOTCLASSPATH_P:
+                       /* Prepend to bootclasspath. */
+                       // FIXME Make boot_class_path const char*.
+                       boot_class_path = (char*) properties_get("sun.boot.class.path");
+                       len = strlen(boot_class_path);
+                       p = MNEW(char, strlen(opt_arg) + strlen(":") + len + strlen("0"));
+                       strcpy(p, opt_arg);
+                       strcat(p, ":");
+                       strcat(p, boot_class_path);
+                       properties_add("sun.boot.class.path", p);
+                       properties_add("java.boot.class.path", p);
+                       MFREE(boot_class_path, char, len);
+                       break;
+               case OPT_BOOTCLASSPATH_C:
+                       /* Use as Java core library, but prepend VM interface
+                          classes. */
+                       // FIXME Make boot_class_path const char*.
+                       boot_class_path = (char*) properties_get("sun.boot.class.path");
+                       len =
+                               strlen(CACAO_VM_ZIP) +
+                               strlen(":") +
+                               strlen(opt_arg) +
+                               strlen("0");
+                       p = MNEW(char, len);
+                       strcpy(p, CACAO_VM_ZIP);
+                       strcat(p, ":");
+                       strcat(p, opt_arg);
+                       properties_add("sun.boot.class.path", p);
+                       properties_add("java.boot.class.path", p);
+                       MFREE(boot_class_path, char, strlen(boot_class_path));
+                       break;
+ #if defined(ENABLE_JVMTI)
+               case OPT_DEBUG:
+                       /* this option exists only for compatibility reasons */
+                       break;
+               case OPT_NOAGENT:
+                       /* I don't know yet what Xnoagent should do. This is only for 
+                          compatiblity with eclipse - motse */
+                       break;
+               case OPT_XRUNJDWP:
+                       agentbypath = true;
+                       jvmti       = true;
+                       jdwp        = true;
+                       len =
+                               strlen(CACAO_LIBDIR) +
+                               strlen("/libjdwp.so=") +
+                               strlen(opt_arg) +
+                               strlen("0");
+                       agentarg = MNEW(char, len);
+                       strcpy(agentarg, CACAO_LIBDIR);
+                       strcat(agentarg, "/libjdwp.so=");
+                       strcat(agentarg, &opt_arg[1]);
+                       break;
+               case OPT_AGENTPATH:
+                       agentbypath = true;
+               case OPT_AGENTLIB:
+                       jvmti = true;
+                       agentarg = opt_arg;
+                       break;
+ #endif
+                       
+               case OPT_MX:
+               case OPT_MS:
+               case OPT_SS:
+                       {
+                               char c;
+                               int j;
+                               c = opt_arg[strlen(opt_arg) - 1];
+                               if ((c == 'k') || (c == 'K')) {
+                                       j = atoi(opt_arg) * 1024;
+                               } else if ((c == 'm') || (c == 'M')) {
+                                       j = atoi(opt_arg) * 1024 * 1024;
+                               } else
+                                       j = atoi(opt_arg);
+                               if (opt == OPT_MX)
+                                       opt_heapmaxsize = j;
+                               else if (opt == OPT_MS)
+                                       opt_heapstartsize = j;
+                               else
+                                       opt_stacksize = j;
+                       }
+                       break;
+               case OPT_VERBOSE1:
+                       opt_verbose = true;
+                       break;
+               case OPT_VERBOSE:
+                       if (strcmp("class", opt_arg) == 0) {
+                               opt_verboseclass = true;
+                       }
+                       else if (strcmp("gc", opt_arg) == 0) {
+                               opt_verbosegc = true;
+                       }
+                       else if (strcmp("jni", opt_arg) == 0) {
+                               opt_verbosejni = true;
+                       }
+ #if !defined(NDEBUG)
+                       else if (strcmp("jit", opt_arg) == 0) {
+                               opt_verbose = true;
+                               loadverbose = true;
+                               initverbose = true;
+                               compileverbose = true;
+                       }
+ #endif
+                       else {
+                               printf("Unknown -verbose option: %s\n", opt_arg);
+                               usage();
+                       }
+                       break;
+               case OPT_DEBUGCOLOR:
+                       opt_debugcolor = true;
+                       break;
+ #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
+               case OPT_VERBOSETC:
+                       opt_typecheckverbose = true;
+                       break;
+ #endif
+                               
+               case OPT_VERSION:
+                       opt_version = true;
+                       opt_exit    = true;
+                       break;
+               case OPT_FULLVERSION:
+                       fullversion();
+                       break;
+               case OPT_SHOWVERSION:
+                       opt_version = true;
+                       break;
+               case OPT_NOIEEE:
+                       opt_noieee = true;
+                       break;
+ #if defined(ENABLE_VERIFIER)
+               case OPT_NOVERIFY:
+                       opt_verify = false;
+                       break;
+ #endif
+ #if defined(ENABLE_STATISTICS)
+               case OPT_TIME:
+                       opt_getcompilingtime = true;
+                       opt_getloadingtime = true;
+                       break;
+                                       
+               case OPT_STAT:
+                       opt_stat = true;
+                       break;
+ #endif
+                                       
+               case OPT_LOG:
+                       log_init(opt_arg);
+                       break;
+                       
+               case OPT_CHECK:
+                       for (unsigned int i = 0; i < strlen(opt_arg); i++) {
+                               switch (opt_arg[i]) {
+                               case 'b':
+                                       checkbounds = false;
+                                       break;
+                               case 's':
+                                       checksync = false;
+                                       break;
+                               default:
+                                       usage();
+                               }
+                       }
+                       break;
+                       
+               case OPT_LOAD:
+                       opt_run = false;
+                       makeinitializations = false;
+                       break;
+ #if !defined(NDEBUG)
+               case OPT_ALL:
+                       compileall = true;
+                       opt_run = false;
+                       makeinitializations = false;
+                       break;
+               case OPT_METHOD:
+                       opt_run = false;
+                       opt_method = opt_arg;
+                       makeinitializations = false;
+                       break;
+               case OPT_SIGNATURE:
+                       opt_signature = opt_arg;
+                       break;
+ #endif
+               case OPT_SHOW:       /* Display options */
+                       for (unsigned int i = 0; i < strlen(opt_arg); i++) {            
+                               switch (opt_arg[i]) {
+                               case 'c':
+                                       showconstantpool = true;
+                                       break;
+                               case 'u':
+                                       showutf = true;
+                                       break;
+                               case 'm':
+                                       showmethods = true;
+                                       break;
+                               case 'i':
+                                       opt_showintermediate = true;
+                                       compileverbose = true;
+                                       break;
+ #if defined(ENABLE_DISASSEMBLER)
+                               case 'a':
+                                       opt_showdisassemble = true;
+                                       compileverbose = true;
+                                       break;
+                               case 'o':
+                                       opt_shownops = true;
+                                       break;
+ #endif
+                               case 'd':
+                                       opt_showddatasegment = true;
+                                       break;
+                               default:
+                                       usage();
+                               }
+                       }
+                       break;
+                       
+ #if defined(ENABLE_LOOP)
+               case OPT_OLOOP:
+                       opt_loops = true;
+                       break;
+ #endif
+ #if defined(ENABLE_IFCONV)
+               case OPT_IFCONV:
+                       opt_ifconv = true;
+                       break;
+ #endif
+ #if defined(ENABLE_LSRA)
+               case OPT_LSRA:
+                       opt_lsra = true;
+                       break;
+ #endif
+ #if  defined(ENABLE_SSA)
+               case OPT_LSRA:
+                       opt_lsra = true;
+                       for (unsigned int i = 0; i < strlen(opt_arg); i++) {            
+                               switch (opt_arg[i]) {
+                               case 'c':
+                                       opt_ssa_cp = true;
+                                       break;
+                               case 'd':
+                                       opt_ssa_dce = true;
+                                       break;
+                               case ':':
+                                       break;
+                               default:
+                                       usage();
+                               }
+                       }
+                       break;
+ #endif
+               case OPT_HELP:
+                       usage();
+                       break;
+               case OPT_X:
+                       Xusage();
+                       break;
+               case OPT_XX:
+                       /* Already parsed. */
+                       break;
+               case OPT_EA:
+ #if defined(ENABLE_ASSERTION)
+                       assertion_ea_da(opt_arg, true);
+ #endif
+                       break;
+               case OPT_DA:
+ #if defined(ENABLE_ASSERTION)
+                       assertion_ea_da(opt_arg, false);
+ #endif
+                       break;
+               case OPT_EA_NOARG:
+ #if defined(ENABLE_ASSERTION)
+                       assertion_user_enabled = true;
+ #endif
+                       break;
+               case OPT_DA_NOARG:
+ #if defined(ENABLE_ASSERTION)
+                       assertion_user_enabled = false;
+ #endif
+                       break;
+               case OPT_ESA:
+ #if defined(ENABLE_ASSERTION)
+                       assertion_system_enabled = true;
+ #endif
+                       break;
+               case OPT_DSA:
+ #if defined(ENABLE_ASSERTION)
+                       assertion_system_enabled = false;
+ #endif
+                       break;
+ #if defined(ENABLE_PROFILING)
+               case OPT_PROF_OPTION:
+                       /* use <= to get the last \0 too */
+                       for (unsigned int i = 0, j = 0; i <= strlen(opt_arg); i++) {
+                               if (opt_arg[i] == ',')
+                                       opt_arg[i] = '\0';
+                               if (opt_arg[i] == '\0') {
+                                       if (strcmp("bb", opt_arg + j) == 0)
+                                               opt_prof_bb = true;
+                                       else {
+                                               printf("Unknown option: -Xprof:%s\n", opt_arg + j);
+                                               usage();
+                                       }
+                                       /* set k to next char */
+                                       j = i + 1;
+                               }
+                       }
+                       /* fall through */
+               case OPT_PROF:
+                       opt_prof = true;
+                       break;
+ #endif
+               case OPT_JIT:
+ #if defined(ENABLE_JIT)
+                       opt_jit = true;
+ #else
+                       printf("-Xjit option not enabled.\n");
+                       exit(1);
+ #endif
+                       break;
+               case OPT_INTRP:
+ #if defined(ENABLE_INTRP)
+                       opt_intrp = true;
+ #else
+                       printf("-Xint option not enabled.\n");
+                       exit(1);
+ #endif
+                       break;
+ #if defined(ENABLE_INTRP)
+               case OPT_STATIC_SUPERS:
+                       opt_static_supers = atoi(opt_arg);
+                       break;
+               case OPT_NO_DYNAMIC:
+                       opt_no_dynamic = true;
+                       break;
+               case OPT_NO_REPLICATION:
+                       opt_no_replication = true;
+                       break;
+               case OPT_NO_QUICKSUPER:
+                       opt_no_quicksuper = true;
+                       break;
+               case OPT_TRACE:
+                       vm_debug = true;
+                       break;
+ #endif
+ #if defined(ENABLE_DEBUG_FILTER)
+               case OPT_FILTER_VERBOSECALL_INCLUDE:
+                       opt_filter_verbosecall_include = opt_arg;
+                       break;
+               case OPT_FILTER_VERBOSECALL_EXCLUDE:
+                       opt_filter_verbosecall_exclude = opt_arg;
+                       break;
+               case OPT_FILTER_SHOW_METHOD:
+                       opt_filter_show_method = opt_arg;
+                       break;
+ #endif
+               default:
+                       printf("Unknown option: %s\n",
+                                  vm_args->options[opt_index].optionString);
+                       usage();
+               }
+       }
+ #if defined(ENABLE_JVMTI)
+       if (jvmti) {
+               jvmti_set_phase(JVMTI_PHASE_ONLOAD);
+               jvmti_agentload(agentarg, agentbypath, &handle, &libname);
+               if (jdwp)
+                       MFREE(agentarg, char, strlen(agentarg));
+               jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
+       }
+ #endif
+       /* initialize the garbage collector */
+       gc_init(opt_heapmaxsize, opt_heapstartsize);
+ #if defined(ENABLE_THREADS)
+       /* BEFORE: threads_preinit */
+       threadlist_init();
+       /* AFTER: gc_init */
+       threads_preinit();
+       lock_init();
+ #endif
+       /* install architecture dependent signal handlers */
+       if (!signal_init())
+               vm_abort("vm_create: signal_init failed");
+ #if defined(ENABLE_INTRP)
+       /* Allocate main thread stack on the Java heap. */
+       if (opt_intrp) {
+               intrp_main_stack = GCMNEW(u1, opt_stacksize);
+               MSET(intrp_main_stack, 0, u1, opt_stacksize);
+       }
+ #endif
+       /* AFTER: threads_preinit */
+       if (!string_init())
+               vm_abort("vm_create: string_init failed");
+       /* AFTER: threads_preinit */
+       utf8_init();
+       /* AFTER: thread_preinit */
+       if (!suck_init())
+               vm_abort("vm_create: suck_init failed");
+       suck_add_from_property("java.endorsed.dirs");
+       /* Now we have all options handled and we can print the version
+          information.
+          AFTER: suck_add_from_property("java.endorsed.dirs"); */
+       if (opt_version)
+               version(opt_exit);
+       /* AFTER: utf8_init */
+       // FIXME Make boot_class_path const char*.
+       boot_class_path = (char*) properties_get("sun.boot.class.path");
+       suck_add(boot_class_path);
+       /* initialize the classcache hashtable stuff: lock, hashtable
+          (must be done _after_ threads_preinit) */
+       if (!classcache_init())
+               vm_abort("vm_create: classcache_init failed");
+       /* Initialize the code memory management. */
+       /* AFTER: threads_preinit */
+       codememory_init();
+       /* initialize the finalizer stuff (must be done _after_
+          threads_preinit) */
+       if (!finalizer_init())
+               vm_abort("vm_create: finalizer_init failed");
+       /* Initialize the JIT compiler. */
+       jit_init();
+       code_init();
+       methodtree_init();
+ #if defined(ENABLE_PYTHON)
+       pythonpass_init();
+ #endif
+       /* BEFORE: loader_preinit */
+       Package::initialize();
+       /* AFTER: utf8_init, classcache_init */
+       loader_preinit();
+       linker_preinit();
+       /* AFTER: loader_preinit, linker_preinit */
+       primitive_init();
+       loader_init();
+       linker_init();
+       /* AFTER: loader_init, linker_init */
+       primitive_postinit();
+       method_init();
+ #if defined(ENABLE_JIT)
+       trap_init();
+ #endif
+       if (!builtin_init())
+               vm_abort("vm_create: builtin_init failed");
+       /* Initialize the native subsystem. */
+       /* BEFORE: threads_init */
+       if (!native_init())
+               vm_abort("vm_create: native_init failed");
+       /* Register the native methods implemented in the VM. */
+       /* BEFORE: threads_init */
+       nativevm_preinit();
+ #if defined(ENABLE_JNI)
+       /* Initialize the JNI subsystem (must be done _before_
+          threads_init, as threads_init can call JNI methods
+          (e.g. NewGlobalRef). */
+       if (!jni_init())
+               vm_abort("vm_create: jni_init failed");
+ #endif
+ #if defined(ENABLE_JNI) || defined(ENABLE_HANDLES)
+       /* Initialize the local reference table for the main thread. */
+       /* BEFORE: threads_init */
+       if (!localref_table_init())
+               vm_abort("vm_create: localref_table_init failed");
+ #endif
+       /* Iinitialize some important system classes. */
+       /* BEFORE: threads_init */
+       initialize_init();
+ #if defined(ENABLE_THREADS)
+       threads_init();
+ #endif
+       /* Initialize the native VM subsystem. */
+       /* AFTER: threads_init (at least for SUN's classes) */
+       nativevm_init();
+ #if defined(ENABLE_PROFILING)
+       /* initialize profiling */
+       if (!profile_init())
+               vm_abort("vm_create: profile_init failed");
+ #endif
+ #if defined(ENABLE_THREADS)
+       /* initialize recompilation */
+       if (!recompile_init())
+               vm_abort("vm_create: recompile_init failed");
+       /* start the signal handler thread */
+ #if defined(__LINUX__)
+       /* XXX Remove for exact-GC. */
+       if (threads_pthreads_implementation_nptl)
+ #endif
+               if (!signal_start_thread())
+                       vm_abort("vm_create: signal_start_thread failed");
+       /* finally, start the finalizer thread */
+       if (!finalizer_start_thread())
+               vm_abort("vm_create: finalizer_start_thread failed");
+ # if !defined(NDEBUG)
+       /* start the memory profiling thread */
+       if (opt_ProfileMemoryUsage || opt_ProfileGCMemoryUsage)
+               if (!memory_start_thread())
+                       vm_abort("vm_create: memory_start_thread failed");
+ # endif
+       /* start the recompilation thread (must be done before the
+          profiling thread) */
+       if (!recompile_start_thread())
+               vm_abort("vm_create: recompile_start_thread failed");
+ # if defined(ENABLE_PROFILING)
+       /* start the profile sampling thread */
+ /*    if (opt_prof) */
+ /*            if (!profile_start_thread()) */
+ /*                    vm_abort("vm_create: profile_start_thread failed"); */
+ # endif
+ #endif
+ #if defined(ENABLE_JVMTI)
+ # if defined(ENABLE_GC_CACAO)
+       /* XXX this will not work with the new indirection cells for classloaders!!! */
+       assert(0);
+ # endif
+       if (jvmti) {
+               /* add agent library to native library hashtable */
+               native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
+       }
+ #endif
+       /* Increment the number of VMs. */
+       vms++;
+       // Initialization is done, VM is created.
+       _created      = true;
+       _initializing = false;
+       
+       /* Print the VM configuration after all stuff is set and the VM is
+          initialized. */
+       if (opt_PrintConfig)
+               vm_printconfig();
+ }
+ /* vm_run **********************************************************************
+    Runs the main-method of the passed class.
+ *******************************************************************************/
+ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
+ {
+       char*                      option;
+       char*                      mainname;
+       char*                      p;
+       utf                       *mainutf;
+       classinfo                 *mainclass;
+       java_handle_t             *e;
+       methodinfo                *m;
+       java_handle_objectarray_t *oa; 
+       s4                         oalength;
+       utf                       *u;
+       java_handle_t             *s;
+       int                        status;
+       // Prevent compiler warnings.
+       oa = NULL;
+ #if !defined(NDEBUG)
+       if (compileall) {
+               vm_compile_all();
+               return;
+       }
+ #endif
+       /* Get the main class plus it's arguments. */
+       mainname = NULL;
+       if (opt_index < vm_args->nOptions) {
+               /* Get main-class argument. */
+               mainname = vm_args->options[opt_index].optionString;
+               /* If the main class argument is a jar file, put it into the
+                  classpath. */
+               if (opt_jar == true) {
+                       p = MNEW(char, strlen(mainname) + strlen("0"));
+                       strcpy(p, mainname);
+ #if defined(ENABLE_JAVASE)
+                       properties_add("java.class.path", p);
+ #endif
+               }
+               else {
+                       /* Replace dots with slashes in the class name. */
+                       for (unsigned int i = 0; i < strlen(mainname); i++)
+                               if (mainname[i] == '.')
+                                       mainname[i] = '/';
+               }
+               /* Build argument array.  Move index to first argument. */
+               opt_index++;
+               oalength = vm_args->nOptions - opt_index;
+               oa = builtin_anewarray(oalength, class_java_lang_String);
+               for (int i = 0; i < oalength; i++) {
+                       option = vm_args->options[opt_index + i].optionString;
+                       u = utf_new_char(option);
+                       s = javastring_new(u);
+                       array_objectarray_element_set(oa, i, s);
+               }
+       }
+       /* Do we have a main-class argument? */
+       if (mainname == NULL)
+               usage();
+ #if !defined(NDEBUG)
+       if (opt_method != NULL) {
+               vm_compile_method(mainname);
+               return;
+       }
+ #endif
+       /* set return value to OK */
+       status = 0;
+       if (opt_jar == true) {
+               /* open jar file with java.util.jar.JarFile */
+               mainname = vm_get_mainclass_from_jar(mainname);
+               if (mainname == NULL)
+                       vm_exit(1);
+       }
+       /* load the main class */
+       mainutf = utf_new_char(mainname);
+ #if defined(ENABLE_JAVAME_CLDC1_1)
+       mainclass = load_class_bootstrap(mainutf);
+ #else
+       mainclass = load_class_from_sysloader(mainutf);
+ #endif
+       /* error loading class */
+       e = exceptions_get_and_clear_exception();
+       if ((e != NULL) || (mainclass == NULL)) {
+               exceptions_throw_noclassdeffounderror_cause(e);
+               exceptions_print_stacktrace(); 
+               vm_exit(1);
+       }
+       if (!link_class(mainclass)) {
+               exceptions_print_stacktrace();
+               vm_exit(1);
+       }
+                       
+       /* find the `main' method of the main class */
+       m = class_resolveclassmethod(mainclass,
+                                                                utf_new_char("main"), 
+                                                                utf_new_char("([Ljava/lang/String;)V"),
+                                                                class_java_lang_Object,
+                                                                false);
+       if (exceptions_get_exception()) {
+               exceptions_print_stacktrace();
+               vm_exit(1);
+       }
+       /* there is no main method or it isn't static */
+       if ((m == NULL) || !(m->flags & ACC_STATIC)) {
+               exceptions_clear_exception();
+               exceptions_throw_nosuchmethoderror(mainclass,
+                                                                                  utf_new_char("main"), 
+                                                                                  utf_new_char("([Ljava/lang/String;)V"));
+               exceptions_print_stacktrace();
+               vm_exit(1);
+       }
+ #ifdef TYPEINFO_DEBUG_TEST
+       /* test the typeinfo system */
+       typeinfo_test();
+ #endif
+ #if defined(ENABLE_JVMTI)
+       jvmti_set_phase(JVMTI_PHASE_LIVE);
+ #endif
+       /* set ThreadMXBean variables */
+ //    _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
+ //    _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
+ //    if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
+ //            _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
+ //            _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
+ //                    _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
+ #warning Move to C++
+       /* start the main thread */
+       (void) vm_call_method(m, NULL, oa);
+       /* exception occurred? */
+       if (exceptions_get_exception()) {
+               exceptions_print_stacktrace();
+               status = 1;
+       }
+ #if defined(ENABLE_THREADS)
+     /* Detach the main thread so that it appears to have ended when
+          the application's main method exits. */
+       if (!thread_detach_current_thread())
+               vm_abort("vm_run: Could not detach main thread.");
+ #endif
+       /* Destroy the JavaVM. */
+       (void) vm_destroy(vm);
+       /* And exit. */
+       vm_exit(status);
+ }
+ /* vm_destroy ******************************************************************
+    Unloads a Java VM and reclaims its resources.
+ *******************************************************************************/
+ int vm_destroy(JavaVM *vm)
+ {
+ #if defined(ENABLE_THREADS)
+       /* Create a a trivial new Java waiter thread called
+          "DestroyJavaVM". */
+       JavaVMAttachArgs args;
+       args.name  = (char*) "DestroyJavaVM";
+       args.group = NULL;
+       if (!thread_attach_current_thread(&args, false))
+               return 1;
+       /* Wait until we are the last non-daemon thread. */
+       threads_join_all_threads();
+ #endif
+       /* VM is gone. */
+ //    _created = false;
+ #warning Move to C++
+       /* Everything is ok. */
+       return 0;
+ }
+ /* vm_exit *********************************************************************
+    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
+ *******************************************************************************/
+ void vm_exit(s4 status)
+ {
+       methodinfo *m;
+       /* signal that we are exiting */
+ //    _exiting = true;
+ #warning Move to C++
+       assert(class_java_lang_System);
+       assert(class_java_lang_System->state & CLASS_LOADED);
+ #if defined(ENABLE_JVMTI)
+       if (jvmti || (dbgcom!=NULL)) {
+               jvmti_set_phase(JVMTI_PHASE_DEAD);
+               if (jvmti) jvmti_agentunload();
+       }
+ #endif
+       if (!link_class(class_java_lang_System)) {
+               exceptions_print_stacktrace();
+               exit(1);
+       }
+       /* call java.lang.System.exit(I)V */
+       m = class_resolveclassmethod(class_java_lang_System,
+                                                                utf_new_char("exit"),
+                                                                utf_int__void,
+                                                                class_java_lang_Object,
+                                                                true);
+       
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               exit(1);
+       }
+       /* call the exit function with passed exit status */
+       (void) vm_call_method(m, NULL, status);
+       /* If we had an exception, just ignore the exception and exit with
+          the proper code. */
+       vm_shutdown(status);
+ }
+ /* vm_shutdown *****************************************************************
+    Terminates the system immediately without freeing memory explicitly
+    (to be used only for abnormal termination).
+       
+ *******************************************************************************/
+ void vm_shutdown(s4 status)
+ {
+       if (opt_verbose 
+ #if defined(ENABLE_STATISTICS)
+               || opt_getcompilingtime || opt_stat
+ #endif
+          ) 
+       {
+               log_text("CACAO terminated by shutdown");
+               dolog("Exit status: %d\n", (s4) status);
+       }
+ #if defined(ENABLE_JVMTI)
+       /* terminate cacaodbgserver */
+       if (dbgcom!=NULL) {
+               mutex_lock(&dbgcomlock);
+               dbgcom->running=1;
+               mutex_unlock(&dbgcomlock);
+               jvmti_cacaodbgserver_quit();
+       }       
+ #endif
++#if defined (ENABLE_JITCACHE)
++  jitcache_quit();
++#endif
++
+       exit(status);
+ }
+ /* vm_exit_handler *************************************************************
+    The exit_handler function is called upon program termination.
+    ATTENTION: Don't free system resources here! Some threads may still
+    be running as this is called from VMRuntime.exit(). The OS does the
+    cleanup for us.
+ *******************************************************************************/
+ void vm_exit_handler(void)
+ {
+ #if !defined(NDEBUG)
+       if (showmethods)
+               class_showmethods(mainclass);
+       if (showconstantpool)
+               class_showconstantpool(mainclass);
+       if (showutf)
+               utf_show();
+ # if defined(ENABLE_PROFILING)
+       if (opt_prof)
+               profile_printstats();
+ # endif
+ #endif /* !defined(NDEBUG) */
+ #if defined(ENABLE_RT_TIMING)
+       rt_timing_print_time_stats(stderr);
+ #endif
+ #if defined(ENABLE_CYCLES_STATS)
+       builtin_print_cycles_stats(stderr);
+       stacktrace_print_cycles_stats(stderr);
+ #endif
+       if (opt_verbose 
+ #if defined(ENABLE_STATISTICS)
+               || opt_getcompilingtime || opt_stat
+ #endif
+          ) 
+       {
+               log_text("CACAO terminated");
+ #if defined(ENABLE_STATISTICS)
+               if (opt_stat) {
+                       print_stats();
+ #ifdef TYPECHECK_STATISTICS
+                       typecheck_print_statistics(get_logfile());
+ #endif
+               }
+               if (opt_getcompilingtime)
+                       print_times();
+ #endif /* defined(ENABLE_STATISTICS) */
+       }
+       /* vm_print_profile(stderr);*/
+ }
+ /* vm_abort ********************************************************************
+    Prints an error message and aborts the VM.
+    IN:
+        text ... error message to print
+ *******************************************************************************/
+ void vm_abort(const char *text, ...)
+ {
+       va_list ap;
+       /* Print the log message. */
+       log_start();
+       va_start(ap, text);
+       log_vprint(text, ap);
+       va_end(ap);
+       log_finish();
+       /* Now abort the VM. */
+       os::abort();
+ }
+ /* vm_abort_errnum *************************************************************
+    Prints an error message, appends ":" plus the strerror-message of
+    errnum and aborts the VM.
+    IN:
+        errnum ... error number
+        text ..... error message to print
+ *******************************************************************************/
+ void vm_abort_errnum(int errnum, const char *text, ...)
+ {
+       va_list ap;
+       /* Print the log message. */
+       log_start();
+       va_start(ap, text);
+       log_vprint(text, ap);
+       va_end(ap);
+       /* Print the strerror-message of errnum. */
+       log_print(": %s", os::strerror(errnum));
+       log_finish();
+       /* Now abort the VM. */
+       os::abort();
+ }
+ /* vm_abort_errno **************************************************************
+    Equal to vm_abort_errnum, but uses errno to get the error number.
+    IN:
+        text ... error message to print
+ *******************************************************************************/
+ void vm_abort_errno(const char *text, ...)
+ {
+       va_list ap;
+       va_start(ap, text);
+       vm_abort_errnum(errno, text, ap);
+       va_end(ap);
+ }
+ /* vm_abort_disassemble ********************************************************
+    Prints an error message, disassemble the given code range (if
+    enabled) and aborts the VM.
+    IN:
+        pc.......PC to disassemble
+          count....number of instructions to disassemble
+ *******************************************************************************/
+ void vm_abort_disassemble(void *pc, int count, const char *text, ...)
+ {
+       va_list ap;
+ #if defined(ENABLE_DISASSEMBLER)
+       int     i;
+ #endif
+       /* Print debug message. */
+       log_start();
+       va_start(ap, text);
+       log_vprint(text, ap);
+       va_end(ap);
+       log_finish();
+       /* Print the PC. */
+ #if SIZEOF_VOID_P == 8
+       log_println("PC=0x%016lx", pc);
+ #else
+       log_println("PC=0x%08x", pc);
+ #endif
+ #if defined(ENABLE_DISASSEMBLER)
+       log_println("machine instructions at PC:");
+       /* Disassemble the given number of instructions. */
+       for (i = 0; i < count; i++)
+               // FIXME disassinstr should use void*.
+               pc = disassinstr((u1*) pc);
+ #endif
+       vm_abort("Aborting...");
+ }
+ /* vm_get_mainclass_from_jar ***************************************************
+    Gets the name of the main class from a JAR's manifest file.
+ *******************************************************************************/
+ static char *vm_get_mainclass_from_jar(char *mainname)
+ {
+       classinfo     *c;
+       java_handle_t *o;
+       methodinfo    *m;
+       java_handle_t *s;
+       c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
+       if (c == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+       /* create JarFile object */
+       o = builtin_new(c);
+       if (o == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+       m = class_resolveclassmethod(c,
+                                                                utf_init, 
+                                                                utf_java_lang_String__void,
+                                                                class_java_lang_Object,
+                                                                true);
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+       s = javastring_new_from_ascii(mainname);
+       (void) vm_call_method(m, o, s);
+       if (exceptions_get_exception()) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+       /* get manifest object */
+       m = class_resolveclassmethod(c,
+                                                                utf_new_char("getManifest"), 
+                                                                utf_new_char("()Ljava/util/jar/Manifest;"),
+                                                                class_java_lang_Object,
+                                                                true);
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+       o = vm_call_method(m, o);
+       if (o == NULL) {
+               fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainname);
+               return NULL;
+       }
+       /* get Main Attributes */
+       LLNI_class_get(o, c);
+       m = class_resolveclassmethod(c,
+                                                                utf_new_char("getMainAttributes"), 
+                                                                utf_new_char("()Ljava/util/jar/Attributes;"),
+                                                                class_java_lang_Object,
+                                                                true);
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+       o = vm_call_method(m, o);
+       if (o == NULL) {
+               fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainname);
+               return NULL;
+       }
+       /* get property Main-Class */
+       LLNI_class_get(o, c);
+       m = class_resolveclassmethod(c,
+                                                                utf_new_char("getValue"), 
+                                                                utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
+                                                                class_java_lang_Object,
+                                                                true);
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+       s = javastring_new_from_ascii("Main-Class");
+       o = vm_call_method(m, o, s);
+       if (o == NULL) {
+               fprintf(stderr, "Failed to load Main-Class manifest attribute from\n");
+               fprintf(stderr, "%s\n", mainname);
+               return NULL;
+       }
+       return javastring_tochar(o);
+ }
+ /* vm_compile_all **************************************************************
+    Compile all methods found in the bootclasspath.
+ *******************************************************************************/
+ #if !defined(NDEBUG)
+ static void vm_compile_all(void)
+ {
+       classinfo              *c;
+       methodinfo             *m;
+       u4                      slot;
+       classcache_name_entry  *nmen;
+       classcache_class_entry *clsen;
+       s4                      i;
+       /* create all classes found in the bootclasspath */
+       /* XXX currently only works with zip/jar's */
+       loader_load_all_classes();
+       /* link all classes */
+       for (slot = 0; slot < hashtable_classcache.size; slot++) {
+               nmen = (classcache_name_entry *) hashtable_classcache.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 == NULL)
+                                       continue;
+                               if (!(c->state & CLASS_LINKED)) {
+                                       if (!link_class(c)) {
+                                               fprintf(stderr, "Error linking: ");
+                                               utf_fprint_printable_ascii_classname(stderr, c->name);
+                                               fprintf(stderr, "\n");
+                                               /* print out exception and cause */
+                                               exceptions_print_current_exception();
+                                               /* goto next class */
+                                               continue;
+                                       }
+                               }
+                               /* compile all class methods */
+                               for (i = 0; i < c->methodscount; i++) {
+                                       m = &(c->methods[i]);
+                                       if (m->jcode != NULL) {
+                                               if (!jit_compile(m)) {
+                                                       fprintf(stderr, "Error compiling: ");
+                                                       utf_fprint_printable_ascii_classname(stderr, c->name);
+                                                       fprintf(stderr, ".");
+                                                       utf_fprint_printable_ascii(stderr, m->name);
+                                                       utf_fprint_printable_ascii(stderr, m->descriptor);
+                                                       fprintf(stderr, "\n");
+                                                       /* print out exception and cause */
+                                                       exceptions_print_current_exception();
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+ }
+ #endif /* !defined(NDEBUG) */
+ /* vm_compile_method ***********************************************************
+    Compile a specific method.
+ *******************************************************************************/
+ #if !defined(NDEBUG)
+ static void vm_compile_method(char* mainname)
+ {
+       methodinfo *m;
+       /* create, load and link the main class */
+       mainclass = load_class_bootstrap(utf_new_char(mainname));
+       if (mainclass == NULL)
+               exceptions_print_stacktrace();
+       if (!link_class(mainclass))
+               exceptions_print_stacktrace();
+       if (opt_signature != NULL) {
+               m = class_resolveclassmethod(mainclass,
+                                                                        utf_new_char(opt_method),
+                                                                        utf_new_char(opt_signature),
+                                                                        mainclass,
+                                                                        false);
+       }
+       else {
+               m = class_resolveclassmethod(mainclass,
+                                                                        utf_new_char(opt_method),
+                                                                        NULL,
+                                                                        mainclass,
+                                                                        false);
+       }
+       if (m == NULL)
+               vm_abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
+                                opt_method, opt_signature ? opt_signature : "");
+               
+       jit_compile(m);
+ }
+ #endif /* !defined(NDEBUG) */
+ /* vm_call_array ***************************************************************
+    Calls a Java method with a variable number of arguments, passed via
+    an argument array.
+    ATTENTION: This function has to be used outside the nativeworld.
+ *******************************************************************************/
+ #define VM_CALL_ARRAY(name, type)                                 \
+ static type vm_call##name##_array(methodinfo *m, uint64_t *array) \
+ {                                                                 \
+       methoddesc *md;                                               \
+       void       *pv;                                               \
+       type        value;                                            \
+                                                                   \
+       assert(m->code != NULL);                                      \
+                                                                   \
+       md = m->parseddesc;                                           \
+       pv = m->code->entrypoint;                                     \
+                                                                   \
+       STATISTICS(count_calls_native_to_java++);                     \
+                                                                   \
+       value = asm_vm_call_method##name(pv, array, md->memuse);      \
+                                                                   \
+       return value;                                                 \
+ }
+ static java_handle_t *vm_call_array(methodinfo *m, uint64_t *array)
+ {
+       methoddesc    *md;
+       void          *pv;
+       java_object_t *o;
+       assert(m->code != NULL);
+       md = m->parseddesc;
+       pv = m->code->entrypoint;
+       STATISTICS(count_calls_native_to_java++);
+       o = asm_vm_call_method(pv, array, md->memuse);
+       if (md->returntype.type == TYPE_VOID)
+               o = NULL;
+       return LLNI_WRAP(o);
+ }
+ VM_CALL_ARRAY(_int,    int32_t)
+ VM_CALL_ARRAY(_long,   int64_t)
+ VM_CALL_ARRAY(_float,  float)
+ VM_CALL_ARRAY(_double, double)
+ /* vm_call_method **************************************************************
+    Calls a Java method with a variable number of arguments.
+ *******************************************************************************/
+ #define VM_CALL_METHOD(name, type)                                  \
+ type vm_call_method##name(methodinfo *m, java_handle_t *o, ...)     \
+ {                                                                   \
+       va_list ap;                                                     \
+       type    value;                                                  \
+                                                                     \
+       va_start(ap, o);                                                \
+       value = vm_call_method##name##_valist(m, o, ap);                \
+       va_end(ap);                                                     \
+                                                                     \
+       return value;                                                   \
+ }
+ VM_CALL_METHOD(,        java_handle_t *)
+ VM_CALL_METHOD(_int,    int32_t)
+ VM_CALL_METHOD(_long,   int64_t)
+ VM_CALL_METHOD(_float,  float)
+ VM_CALL_METHOD(_double, double)
+ /* vm_call_method_valist *******************************************************
+    Calls a Java method with a variable number of arguments, passed via
+    a va_list.
+ *******************************************************************************/
+ #define VM_CALL_METHOD_VALIST(name, type)                               \
+ type vm_call_method##name##_valist(methodinfo *m, java_handle_t *o,     \
+                                                                  va_list ap)                          \
+ {                                                                       \
+       uint64_t *array;                                                    \
+       type      value;                                                    \
+       int32_t   dumpmarker;                                               \
+                                                                         \
+       if (m->code == NULL)                                                \
+               if (!jit_compile(m))                                            \
+                       return 0;                                                   \
+                                                                         \
+       THREAD_NATIVEWORLD_EXIT;                                            \
+       DMARKER;                                                            \
+                                                                         \
+       array = argument_vmarray_from_valist(m, o, ap);                     \
+       value = vm_call##name##_array(m, array);                            \
+                                                                         \
+       DRELEASE;                                                           \
+       THREAD_NATIVEWORLD_ENTER;                                           \
+                                                                         \
+       return value;                                                       \
+ }
+ VM_CALL_METHOD_VALIST(,        java_handle_t *)
+ VM_CALL_METHOD_VALIST(_int,    int32_t)
+ VM_CALL_METHOD_VALIST(_long,   int64_t)
+ VM_CALL_METHOD_VALIST(_float,  float)
+ VM_CALL_METHOD_VALIST(_double, double)
+ /* vm_call_method_jvalue *******************************************************
+    Calls a Java method with a variable number of arguments, passed via
+    a jvalue array.
+ *******************************************************************************/
+ #define VM_CALL_METHOD_JVALUE(name, type)                               \
+ type vm_call_method##name##_jvalue(methodinfo *m, java_handle_t *o,     \
+                                                          const jvalue *args)                  \
+ {                                                                       \
+       uint64_t *array;                                                    \
+       type      value;                                                    \
+       int32_t   dumpmarker;                                               \
+                                                                         \
+       if (m->code == NULL)                                                \
+               if (!jit_compile(m))                                            \
+                       return 0;                                                   \
+                                                                         \
+       THREAD_NATIVEWORLD_EXIT;                                            \
+       DMARKER;                                                            \
+                                                                         \
+       array = argument_vmarray_from_jvalue(m, o, args);                   \
+       value = vm_call##name##_array(m, array);                            \
+                                                                         \
+       DRELEASE;                                                           \
+       THREAD_NATIVEWORLD_ENTER;                                           \
+                                                                         \
+       return value;                                                       \
+ }
+ VM_CALL_METHOD_JVALUE(,        java_handle_t *)
+ VM_CALL_METHOD_JVALUE(_int,    int32_t)
+ VM_CALL_METHOD_JVALUE(_long,   int64_t)
+ VM_CALL_METHOD_JVALUE(_float,  float)
+ VM_CALL_METHOD_JVALUE(_double, double)
+ /* vm_call_method_objectarray **************************************************
+    Calls a Java method with a variable number if arguments, passed via
+    an objectarray of boxed values. Returns a boxed value.
+ *******************************************************************************/
+ java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o,
+                                                                                 java_handle_objectarray_t *params)
+ {
+       uint64_t      *array;
+       java_handle_t *xptr;
+       java_handle_t *ro;
+       imm_union      value;
+       int32_t        dumpmarker;
+       /* Prevent compiler warnings. */
+       ro = NULL;
+       /* compile methods which are not yet compiled */
+       if (m->code == NULL)
+               if (!jit_compile(m))
+                       return NULL;
+       /* leave the nativeworld */
+       THREAD_NATIVEWORLD_EXIT;
+       /* mark start of dump memory area */
+       DMARKER;
+       /* Fill the argument array from a object-array. */
+       array = argument_vmarray_from_objectarray(m, o, params);
+       if (array == NULL) {
+               /* release dump area */
+               DRELEASE;
+               /* enter the nativeworld again */
+               THREAD_NATIVEWORLD_ENTER;
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+       switch (m->parseddesc->returntype.primitivetype) {
+       case PRIMITIVETYPE_VOID:
+               value.a = vm_call_array(m, array);
+               break;
+       case PRIMITIVETYPE_BOOLEAN:
+       case PRIMITIVETYPE_BYTE:
+       case PRIMITIVETYPE_CHAR:
+       case PRIMITIVETYPE_SHORT:
+       case PRIMITIVETYPE_INT:
+               value.i = vm_call_int_array(m, array);
+               break;
+       case PRIMITIVETYPE_LONG:
+               value.l = vm_call_long_array(m, array);
+               break;
+       case PRIMITIVETYPE_FLOAT:
+               value.f = vm_call_float_array(m, array);
+               break;
+       case PRIMITIVETYPE_DOUBLE:
+               value.d = vm_call_double_array(m, array);
+               break;
+       case TYPE_ADR:
+               ro = vm_call_array(m, array);
+               break;
+       default:
+               vm_abort("vm_call_method_objectarray: invalid return type %d", m->parseddesc->returntype.primitivetype);
+       }
+       /* release dump area */
+       DRELEASE;
+       /* enter the nativeworld again */
+       THREAD_NATIVEWORLD_ENTER;
+       /* box the return value if necesarry */
+       if (m->parseddesc->returntype.primitivetype != TYPE_ADR)
+               ro = Primitive::box(m->parseddesc->returntype.primitivetype, value);
+       /* check for an exception */
+       xptr = exceptions_get_exception();
+       if (xptr != NULL) {
+               /* clear exception pointer, we are calling JIT code again */
+               exceptions_clear_exception();
+               exceptions_throw_invocationtargetexception(xptr);
+       }
+       return ro;
+ }
+ /* Legacy C interface *********************************************************/
+ extern "C" {
+ JavaVM* VM_get_javavm()      { return vm->get_javavm(); }
+ JNIEnv* VM_get_jnienv()      { return vm->get_jnienv(); }
+ bool    VM_is_initializing() { return vm->is_initializing(); }
+ bool    VM_is_created()      { return vm->is_created(); }
+ int64_t VM_get_starttime()   { return vm->get_starttime(); }
+ }
+ /*
+  * These are local overrides for various environment variables in Emacs.
+  * Please do not remove this and leave it at the end of the file, where
+  * Emacs will automagically detect them.
+  * ---------------------------------------------------------------------
+  * Local variables:
+  * mode: c++
+  * indent-tabs-mode: t
+  * c-basic-offset: 4
+  * tab-width: 4
+  * End:
+  * vim:noexpandtab:sw=4:ts=4:
+  */