src/vm/vm.c(usage): added information for jvmti agent for jdwp
[cacao.git] / src / cacao / cacao.c
index b91195677ee5a43417daf2d20f97a5d0d641242c..19bfeccdfdc7f7d8016cadb0ad5e3f9aededb20d 100644 (file)
@@ -1,9 +1,9 @@
 /* src/cacao/cacao.c - contains main() of cacao
 
-   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
-   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
-   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
-   Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+   J. Wenninger, J. Wenninger, Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
+   Contact: cacao@cacaojvm.org
 
    Authors: Reinhard Grafl
 
             Philipp Tomsich
             Christian Thalinger
 
-   This module does the following tasks:
-     - Command line option handling
-     - Calling initialization routines
-     - Calling the class loader
-     - Running the main method
-
-   $Id: cacao.c 2195 2005-04-03 16:53:16Z edwin $
+   $Id: cacao.c 4954 2006-05-25 21:59:49Z motse $
 
 */
 
 
+#include "config.h"
+
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "config.h"
-#include "cacao/cacao.h"
-#include "mm/boehm.h"
-#include "mm/memory.h"
+#include "vm/types.h"
+
 #include "native/jni.h"
-#include "native/native.h"
+#include "native/include/java_lang_String.h"
+
+#if defined(ENABLE_JVMTI)
+#include "native/jvmti/jvmti.h"
+#include "native/jvmti/cacaodbg.h"
+
+#if defined(ENABLE_THREADS)
+#include <pthread.h>
+#endif
+#endif
+
 #include "toolbox/logging.h"
+#include "vm/classcache.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/loader.h"
 #include "vm/options.h"
 #include "vm/statistics.h"
 #include "vm/stringlocal.h"
-#include "vm/tables.h"
-#include "vm/classcache.h"
+#include "vm/suck.h"
+#include "vm/vm.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 
 #include "vm/jit/verify/typeinfo.h"
 #endif
 
-
-/* define heap sizes **********************************************************/
-
-#define HEAP_MAXSIZE      64 * 1024 * 1024; /* default 64MB                   */
-#define HEAP_STARTSIZE    2 * 1024 * 1024;  /* default 2MB                    */
-
-
-/* Invocation API variables ***************************************************/
-
-JavaVM *jvm;                        /* denotes a Java VM                      */
-JNIEnv *env;                        /* pointer to native method interface     */
-JDK1_1InitArgs vm_args;             /* JDK 1.1 VM initialization arguments    */
-
-
-bool cacao_initializing;
-
-char *bootclasspath;                    /* contains the boot classpath        */
-char *classpath;                        /* contains the classpath             */
-
-char *mainstring;
-static classinfo *mainclass;
-
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-void **stackbottom = 0;
-#endif
-
-
-/* define command line options ************************************************/
-
-#define OPT_CLASSPATH        2
-#define OPT_D                3
-#define OPT_MS               4
-#define OPT_MX               5
-#define OPT_VERBOSE1         6
-#define OPT_VERBOSE          7
-#define OPT_VERBOSEGC        8
-#define OPT_VERBOSECALL      9
-#define OPT_NOIEEE           10
-#define OPT_SOFTNULL         11
-#define OPT_TIME             12
-
-#if defined(STATISTICS)
-#define OPT_STAT             13
-#endif /* defined(STATISTICS) */
-
-#define OPT_LOG              14
-#define OPT_CHECK            15
-#define OPT_LOAD             16
-#define OPT_METHOD           17
-#define OPT_SIGNATURE        18
-#define OPT_SHOW             19
-#define OPT_ALL              20
-#define OPT_OLOOP            24
-#define OPT_INLINING        25
-
-#define STATIC_ANALYSIS
-#if defined(STATIC_ANALYSIS)
-# define OPT_RT              26
-# define OPT_XTA             27 
-# define OPT_VTA             28
-#endif /* defined(STATIC_ANALYSIS) */
-
-#define OPT_VERBOSETC        29
-#define OPT_NOVERIFY         30
-#define OPT_LIBERALUTF       31
-#define OPT_VERBOSEEXCEPTION 32
-#define OPT_EAGER            33
-
-#if defined(LSRA)
-# define OPT_LSRA            34
-#endif /* defined(LSRA) */
-
-#define OPT_JAR              35
-#define OPT_BOOTCLASSPATH    36
-#define OPT_BOOTCLASSPATH_A  37
-#define OPT_BOOTCLASSPATH_P  38
-#define OPT_VERSION          39
-
-
-opt_struct opts[] = {
-       { "classpath",         true,  OPT_CLASSPATH },
-       { "cp",                true,  OPT_CLASSPATH },
-       { "D",                 true,  OPT_D },
-       { "Xms",               true,  OPT_MS },
-       { "Xmx",               true,  OPT_MX },
-       { "ms",                true,  OPT_MS },
-       { "mx",                true,  OPT_MX },
-       { "noasyncgc",         false, OPT_IGNORE },
-       { "noverify",          false, OPT_NOVERIFY },
-       { "liberalutf",        false, OPT_LIBERALUTF },
-       { "oss",               true,  OPT_IGNORE },
-       { "ss",                true,  OPT_IGNORE },
-       { "v",                 false, OPT_VERBOSE1 },
-       { "verbose",           false, OPT_VERBOSE },
-       { "verbosegc",         false, OPT_VERBOSEGC },
-       { "verbosecall",       false, OPT_VERBOSECALL },
-       { "verboseexception",  false, OPT_VERBOSEEXCEPTION },
-#ifdef TYPECHECK_VERBOSE
-       { "verbosetc",         false, OPT_VERBOSETC },
-#endif
-#if defined(__ALPHA__)
-       { "noieee",            false, OPT_NOIEEE },
-#endif
-       { "softnull",          false, OPT_SOFTNULL },
-       { "time",              false, OPT_TIME },
-#if defined(STATISTICS)
-       { "stat",              false, OPT_STAT },
-#endif
-       { "log",               true,  OPT_LOG },
-       { "c",                 true,  OPT_CHECK },
-       { "l",                 false, OPT_LOAD },
-    { "eager",             false, OPT_EAGER },
-       { "m",                 true,  OPT_METHOD },
-       { "sig",               true,  OPT_SIGNATURE },
-       { "s",                 true,  OPT_SHOW },
-       { "all",               false, OPT_ALL },
-       { "oloop",             false, OPT_OLOOP },
-       { "i",                 true,  OPT_INLINING },
-#ifdef STATIC_ANALYSIS
-       { "rt",                false, OPT_RT },
-       { "xta",               false, OPT_XTA },
-       { "vta",               false, OPT_VTA },
-#endif
-#ifdef LSRA
-       { "lsra",              false, OPT_LSRA },
+#ifdef TYPECHECK_STATISTICS
+void typecheck_print_statistics(FILE *file);
 #endif
-       { "jar",               false, OPT_JAR },
-       { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
-       { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
-       { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
-       { "version",           false, OPT_VERSION },
-       { NULL,                false, 0 }
-};
-
 
-/******************** interne Function: print_usage ************************
+/* getmainclassfromjar *********************************************************
 
-Prints the correct usage syntax to stdout.
+   Gets the name of the main class form a JAR's manifest file.
 
-***************************************************************************/
+*******************************************************************************/
 
-static void usage()
+static char *getmainclassnamefromjar(char *mainstring)
 {
-       printf("Usage: cacao [options] classname [program arguments]\n\n");
-
-       printf("Options:\n");
-       printf("    -cp <path>               specify a path to look for classes\n");
-       printf("    -classpath <path>        specify a path to look for classes\n");
-       printf("    -jar jarfile             execute a jar file\n");
-       printf("    -D<name>=<value>         add an entry to the property list\n");
-       printf("    -Xmx<size>[kK|mM]        specify the size for the heap\n");
-       printf("    -Xms<size>[kK|mM]        specify the initial size for the heap\n");
-       printf("    -mx<size>[kK|mM]         specify the size for the heap\n");
-       printf("    -ms<size>[kK|mM]         specify the initial size for the heap\n");
-       printf("    -Xbootclasspath:<path>   set search path for bootstrap classes and resources\n");
-       printf("    -Xbootclasspath/a:<path> append to end of bootstrap class path\n");
-       printf("    -Xbootclasspath/p:<path> prepend in front of bootstrap class path\n");
-       printf("          -v ................... write state-information\n");
-       printf("          -verbose ............. write more information\n");
-       printf("          -verbosegc ........... write message for each GC\n");
-       printf("          -verbosecall ......... write message for each call\n");
-       printf("          -verboseexception .... write message for each step of stack unwinding\n");
-#ifdef TYPECHECK_VERBOSE
-       printf("          -verbosetc ........... write debug messages while typechecking\n");
-#endif
-       printf("    -version                 print product version and exit\n");
-#if defined(__ALPHA__)
-       printf("          -noieee .............. don't use ieee compliant arithmetic\n");
-#endif
-       printf("          -noverify ............ don't verify classfiles\n");
-       printf("          -liberalutf........... don't warn about overlong UTF-8 sequences\n");
-       printf("          -softnull ............ use software nullpointer check\n");
-       printf("          -time ................ measure the runtime\n");
-#if defined(STATISTICS)
-       printf("          -stat ................ detailed compiler statistics\n");
-#endif
-       printf("          -log logfile ......... specify a name for the logfile\n");
-       printf("          -c(heck)b(ounds) ..... don't check array bounds\n");
-       printf("                  s(ync) ....... don't check for synchronization\n");
-       printf("          -oloop ............... optimize array accesses in loops\n"); 
-       printf("          -l ................... don't start the class after loading\n");
-       printf("          -eager ............... perform eager class loading and linking\n");
-       printf("          -all ................. compile all methods, no execution\n");
-       printf("          -m ................... compile only a specific method\n");
-       printf("          -sig ................. specify signature for a specific method\n");
-       printf("          -s(how)a(ssembler) ... show disassembled listing\n");
-       printf("                 c(onstants) ... show the constant pool\n");
-       printf("                 d(atasegment).. show data segment listing\n");
-       printf("                 i(ntermediate). show intermediate representation\n");
-       printf("                 m(ethods)...... show class fields and methods\n");
-       printf("                 u(tf) ......... show the utf - hash\n");
-       printf("          -i     n ............. activate inlining\n");
-       printf("                 v ............. inline virtual methods\n");
-       printf("                                 uses/turns rt option on\n");
-       printf("                 e ............. inline methods with exceptions\n");
-       printf("                 p ............. optimize argument renaming\n");
-       printf("                 o ............. inline methods of foreign classes\n");
-#ifdef STATIC_ANALYSIS
-       printf("          -rt .................. use rapid type analysis\n");
-       printf("          -xta ................. use x type analysis\n");
-       printf("          -vta ................. use variable type analysis\n");
-#endif
-#ifdef LSRA
-       printf("          -lsra ................ use linear scan register allocation\n");
-#endif
-
-       /* exit with error code */
+       classinfo         *c;
+       java_objectheader *o;
+       methodinfo        *m;
+       java_lang_String  *s;
 
-       exit(1);
-}   
+       c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
 
+       if (!c)
+               throw_main_exception_exit();
+       
+       /* create JarFile object */
 
-/* version *********************************************************************
-
-   Only prints cacao version information and exits.
+       o = builtin_new(c);
 
-*******************************************************************************/
+       if (!o)
+               throw_main_exception_exit();
 
-static void version()
-{
-       printf("cacao "VERSION"\n");
-       exit(0);
-}
 
+       m = class_resolveclassmethod(c,
+                                                                utf_init, 
+                                                                utf_java_lang_String__void,
+                                                                class_java_lang_Object,
+                                                                true);
 
-#ifdef TYPECHECK_STATISTICS
-void typecheck_print_statistics(FILE *file);
-#endif
+       if (!m)
+               throw_main_exception_exit();
 
+       s = javastring_new_from_ascii(mainstring);
 
+       (void) vm_call_method(m, o, s);
 
-/* getmainclassfromjar ************************************************************
+       if (*exceptionptr)
+               throw_main_exception_exit();
 
-   gets the name of the main class form a jar's manifest file
+       /* get manifest object */
 
-**********************************************************************************/
+       m = class_resolveclassmethod(c,
+                                                                utf_new_char("getManifest"), 
+                                                                utf_new_char("()Ljava/util/jar/Manifest;"),
+                                                                class_java_lang_Object,
+                                                                true);
 
-char *getmainclassnamefromjar(JNIEnv *env, char *mainstring)
-{
-       jclass class;
-       jmethodID mid;
-       jobject obj;
-               
-       class = (*env)->FindClass(env, "java/util/jar/JarFile");
-       if (class == NULL) {
-               log_text("unable to find java.util.jar.JarFile");
+       if (!m)
                throw_main_exception_exit();
-       }
-       
-       mid = (*env)->GetMethodID(NULL, class, "<init>","(Ljava/lang/String;)V");
-       if (mid == NULL) {
-               log_text("unable to find constructor in java.util.jar.JarFile");
-               cacao_exit(1);
-       }
 
-       /* open jarfile */
-       obj = (*env)->NewObject(NULL,class,mid,((*env)->NewStringUTF(NULL,(char*)mainstring)));
-       if ((*env)->ExceptionOccurred(NULL) != NULL) {
-               (*env)->ExceptionDescribe(NULL);
-               cacao_exit(1);
-       }
-       
-       mid = (*env)->GetMethodID(NULL, class, "getManifest","()Ljava/util/jar/Manifest;");
-       if (mid == NULL) {
-               log_text("unable to find getMainfest method");
-               cacao_exit(1);
-       }
+       o = vm_call_method(m, o);
 
-       /* get manifest object */
-       obj = (*env)->CallObjectMethod(NULL,obj,mid);
-       if ((*env)->ExceptionOccurred(NULL) != NULL) {
-               (*env)->ExceptionDescribe(NULL);
-               cacao_exit(1);
+       if (o == NULL) {
+               fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
+               vm_exit(1);
        }
 
-       mid = (*env)->GetMethodID(NULL, (jclass)((java_objectheader*) obj)->vftbl->class, "getMainAttributes","()Ljava/util/jar/Attributes;");
-       if (mid == NULL) {
-               log_text("unable to find getMainAttributes method");
-               cacao_exit(1);
-       }
 
        /* get Main Attributes */
-       obj = (*env)->CallObjectMethod(NULL,obj,mid);
-       if ((*env)->ExceptionOccurred(NULL) != NULL) {
-               (*env)->ExceptionDescribe(NULL);
-               cacao_exit(1);
-       }
 
+       m = class_resolveclassmethod(o->vftbl->class,
+                                                                utf_new_char("getMainAttributes"), 
+                                                                utf_new_char("()Ljava/util/jar/Attributes;"),
+                                                                class_java_lang_Object,
+                                                                true);
 
-       mid = (*env)->GetMethodID(NULL, (jclass)((java_objectheader*) obj)->vftbl->class, "getValue","(Ljava/lang/String;)Ljava/lang/String;");
-       if (mid == NULL) {
-               log_text("unable to find getValue method");
-               cacao_exit(1);
-       }
+       if (!m)
+               throw_main_exception_exit();
 
-       /* get property Main-Class */
-       obj = (*env)->CallObjectMethod(NULL,obj,mid,(*env)->NewStringUTF(NULL,"Main-Class"));
-       if ((*env)->ExceptionOccurred(NULL) != NULL) {
-               (*env)->ExceptionDescribe(NULL);
-               cacao_exit(1);
+       o = vm_call_method(m, o);
+
+       if (o == NULL) {
+               fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
+               vm_exit(1);
        }
-       
-       return javastring_tochar((java_objectheader *) obj);
-}
 
 
-/*
- * void exit_handler(void)
- * -----------------------
- * The exit_handler function is called upon program termination to shutdown
- * the various subsystems and release the resources allocated to the VM.
- */
-void exit_handler(void)
-{
-       /********************* Print debug tables ************************/
-                               
-       if (showmethods) class_showmethods(mainclass);
-       if (showconstantpool) class_showconstantpool(mainclass);
-       if (showutf) utf_show();
-
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-       clear_thread_flags();           /* restores standard file descriptor
-                                      flags */
-#endif
+       /* get property Main-Class */
 
-       /************************ Free all resources *******************/
+       m = class_resolveclassmethod(o->vftbl->class,
+                                                                utf_new_char("getValue"), 
+                                                                utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
+                                                                class_java_lang_Object,
+                                                                true);
 
-       loader_close();
-       tables_close();
+       if (!m)
+               throw_main_exception_exit();
 
-       MFREE(classpath, u1, strlen(classpath));
+       s = javastring_new_from_ascii("Main-Class");
 
-       if (opt_verbose || getcompilingtime || opt_stat) {
-               log_text("CACAO terminated");
+       o = vm_call_method(m, o, s);
 
-#if defined(STATISTICS)
-               if (opt_stat) {
-                       print_stats();
-#ifdef TYPECHECK_STATISTICS
-                       typecheck_print_statistics(get_logfile());
-#endif
-               }
+       if (!o)
+               throw_main_exception_exit();
 
-               if (getcompilingtime)
-                       print_times();
-               mem_usagelog(1);
-#endif
-       }
+       return javastring_tochar(o);
 }
 
+void exit_handler(void);
+
+
 
-/************************** Function: main *******************************
+/* main ************************************************************************
 
    The main program.
    
-**************************************************************************/
+*******************************************************************************/
 
 int main(int argc, char **argv)
 {
-       s4 i, j;
-       void *dummy;
-       
-       /********** interne (nur fuer main relevante Optionen) **************/
-   
-       char logfilename[200] = "";
-       u4 heapmaxsize;
-       u4 heapstartsize;
-       char *cp;
-       s4    cplen;
-       bool startit = true;
-       char *specificmethodname = NULL;
-       char *specificsignature = NULL;
-       bool jar = false;
-
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-       stackbottom = &dummy;
-#endif
+       s4 i;
        
-       if (atexit(exit_handler))
-               throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                                  "Unable to register exit_handler");
-
-
-       /************ Collect info from the environment ************************/
-
-       /* set the bootclasspath */
+       /* local variables ********************************************************/
 
-       cp = getenv("BOOTCLASSPATH");
-       if (cp) {
-               bootclasspath = MNEW(char, strlen(cp) + 1);
-               strcpy(bootclasspath, cp);
+       JavaVMInitArgs *vm_args;
+       JavaVM         *jvm;                /* denotes a Java VM                  */
 
-       } else {
-#if !defined(WITH_EXTERNAL_CLASSPATH)
-               cplen = strlen(CACAO_INSTALL_PREFIX) + strlen(CACAO_RT_JAR_PATH);
-
-               bootclasspath = MNEW(char, cplen + 1);
-               strcpy(bootclasspath, CACAO_INSTALL_PREFIX);
-               strcat(bootclasspath, CACAO_RT_JAR_PATH);
-#else
-               cplen = strlen(CACAO_INSTALL_PREFIX) + strlen(CACAO_VM_ZIP_PATH) +
-                       strlen(EXTERNAL_CLASSPATH_PREFIX) + strlen(CLASSPATH_GLIBJ_ZIP_PATH);
-
-               bootclasspath = MNEW(char, cplen + 1 + 1);
-               strcpy(bootclasspath, CACAO_INSTALL_PREFIX);
-               strcat(bootclasspath, CACAO_VM_ZIP_PATH);
-               strcat(bootclasspath, ":");
-               strcat(bootclasspath, EXTERNAL_CLASSPATH_PREFIX);
-               strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
-#endif
-       }
-
-
-       /* set the classpath */
-
-       cp = getenv("CLASSPATH");
-       if (cp) {
-               classpath = MNEW(char, strlen(cp) + 1);
-               strcat(classpath, cp);
-
-       } else {
-               classpath = MNEW(char, 2);
-               strcpy(classpath, ".");
-       }
-
-
-       /***************** Interpret the command line *****************/
-   
-       checknull = false;
-       opt_noieee = false;
-
-       heapmaxsize = HEAP_MAXSIZE;
-       heapstartsize = HEAP_STARTSIZE;
-
-
-       while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
-               switch (i) {
-               case OPT_IGNORE:
-                       break;
-                       
-               case OPT_BOOTCLASSPATH:
-                       /* Forget default bootclasspath and set the argument as new boot  */
-                       /* classpath.                                                     */
-                       MFREE(bootclasspath, char, strlen(bootclasspath));
-
-                       bootclasspath = MNEW(char, strlen(opt_arg) + 1);
-                       strcpy(bootclasspath, opt_arg);
-                       break;
-
-               case OPT_BOOTCLASSPATH_A:
-                       /* append to end of bootclasspath */
-                       cplen = strlen(bootclasspath);
-
-                       bootclasspath = MREALLOC(bootclasspath,
-                                                                        char,
-                                                                        cplen,
-                                                                        cplen + 1 + strlen(opt_arg) + 1);
-
-                       strcat(bootclasspath, ":");
-                       strcat(bootclasspath, opt_arg);
-                       break;
-
-               case OPT_BOOTCLASSPATH_P:
-                       /* prepend in front of bootclasspath */
-                       cp = bootclasspath;
-                       cplen = strlen(cp);
-
-                       bootclasspath = MNEW(char, strlen(opt_arg) + 1 + cplen + 1);
-
-                       strcpy(bootclasspath, opt_arg);
-                       strcat(bootclasspath, ":");
-                       strcat(bootclasspath, cp);
-
-                       MFREE(cp, char, cplen);
-                       break;
-
-               case OPT_CLASSPATH:
-                       /* forget old classpath and set the argument as new classpath */
-                       MFREE(classpath, char, strlen(classpath));
-
-                       classpath = MNEW(char, strlen(opt_arg) + 1);
-                       strcpy(classpath, opt_arg);
-                       break;
-
-               case OPT_JAR:
-                       jar = true;
-                       break;
-                       
-               case OPT_D:
-                       {
-                               for (j = 0; j < strlen(opt_arg); j++) {
-                                       if (opt_arg[j] == '=') {
-                                               opt_arg[j] = '\0';
-                                               create_property(opt_arg, opt_arg + j + 1);
-                                               goto didit;
-                                       }
-                               }
-
-                               /* if no '=' is given, just create an empty property */
-                               create_property(opt_arg, "");
-                                       
-                       didit: ;
-                       }       
-                       break;
-
-               case OPT_MS:
-               case OPT_MX:
-                       {
-                               char c;
-                               c = opt_arg[strlen(opt_arg) - 1];
-
-                               if (c == 'k' || c == 'K') {
-                                       j = 1024 * atoi(opt_arg);
-
-                               } else if (c == 'm' || c == 'M') {
-                                       j = 1024 * 1024 * atoi(opt_arg);
-
-                               } else j = atoi(opt_arg);
-
-                               if (i == OPT_MX) heapmaxsize = j;
-                               else heapstartsize = j;
-                       }
-                       break;
-
-               case OPT_VERBOSE1:
-                       opt_verbose = true;
-                       break;
-
-               case OPT_VERBOSE:
-                       opt_verbose = true;
-                       loadverbose = true;
-                       linkverbose = true;
-                       initverbose = true;
-                       compileverbose = true;
-                       break;
-
-               case OPT_VERBOSEEXCEPTION:
-                       verboseexception = true;
-                       break;
-
-               case OPT_VERBOSEGC:
-                       collectverbose = true;
-                       break;
-
-#ifdef TYPECHECK_VERBOSE
-               case OPT_VERBOSETC:
-                       typecheckverbose = true;
-                       break;
-#endif
-                               
-               case OPT_VERBOSECALL:
-                       runverbose = true;
-                       break;
-
-               case OPT_VERSION:
-                       version();
-                       break;
-
-               case OPT_NOIEEE:
-                       opt_noieee = true;
-                       break;
-
-               case OPT_NOVERIFY:
-                       opt_verify = false;
-                       break;
-
-               case OPT_LIBERALUTF:
-                       opt_liberalutf = true;
-                       break;
-
-               case OPT_SOFTNULL:
-                       checknull = true;
-                       break;
-
-               case OPT_TIME:
-                       getcompilingtime = true;
-                       getloadingtime = true;
-                       break;
-                                       
-#if defined(STATISTICS)
-               case OPT_STAT:
-                       opt_stat = true;
-                       break;
-#endif
-                                       
-               case OPT_LOG:
-                       strcpy(logfilename, opt_arg);
-                       break;
-                       
-               case OPT_CHECK:
-                       for (j = 0; j < strlen(opt_arg); j++) {
-                               switch (opt_arg[j]) {
-                               case 'b':
-                                       checkbounds = false;
-                                       break;
-                               case 's':
-                                       checksync = false;
-                                       break;
-                               default:
-                                       usage();
-                               }
-                       }
-                       break;
-                       
-               case OPT_LOAD:
-                       startit = false;
-                       makeinitializations = false;
-                       break;
-
-               case OPT_EAGER:
-                       opt_eager = true;
-                       break;
-
-               case OPT_METHOD:
-                       startit = false;
-                       specificmethodname = opt_arg;
-                       makeinitializations = false;
-                       break;
-                       
-               case OPT_SIGNATURE:
-                       specificsignature = opt_arg;
-                       break;
-                       
-               case OPT_ALL:
-                       compileall = true;
-                       startit = false;
-                       makeinitializations = false;
-                       break;
-                       
-               case OPT_SHOW:       /* Display options */
-                       for (j = 0; j < strlen(opt_arg); j++) {         
-                               switch (opt_arg[j]) {
-                               case 'a':
-                                       showdisassemble = true;
-                                       compileverbose = true;
-                                       break;
-                               case 'c':
-                                       showconstantpool = true;
-                                       break;
-                               case 'd':
-                                       showddatasegment = true;
-                                       break;
-                               case 'i':
-                                       showintermediate = true;
-                                       compileverbose = true;
-                                       break;
-                               case 'm':
-                                       showmethods = true;
-                                       break;
-                               case 'u':
-                                       showutf = true;
-                                       break;
-                               default:
-                                       usage();
-                               }
-                       }
-                       break;
-                       
-               case OPT_OLOOP:
-                       opt_loops = true;
-                       break;
-
-               case OPT_INLINING:
-                       for (j = 0; j < strlen(opt_arg); j++) {         
-                               switch (opt_arg[j]) {
-                               case 'n':
-                                    /* define in options.h; Used in main.c, jit.c & inline.c */
-#ifdef INAFTERMAIN
-                                       useinliningm = true;
-                                       useinlining = false;
-#else
-                                       useinlining = true;
-#endif
-                                       break;
-                               case 'v':
-                                       inlinevirtuals = true;
-                                       opt_rt = true;
-                                       break;
-                               case 'e':
-                                       inlineexceptions = true;
-                                       break;
-                               case 'p':
-                                       inlineparamopt = true;
-                                       break;
-                               case 'o':
-                                       inlineoutsiders = true;
-                                       break;
-                               default:
-                                       usage();
-                               }
-                       }
-                       break;
-
-#ifdef STATIC_ANALYSIS
-               case OPT_RT:
-                       opt_rt = true; /* default for inlining */
-                       break;
-
-               case OPT_XTA:
-                       opt_xta = true; /* in test currently */
-                       break;
-
-               case OPT_VTA:
-                       printf("\nVTA is not yet available\n");
-                       opt_vta = false;
-                       /***opt_vta = true; not yet **/
-                       break;
-#endif
-
-#ifdef LSRA
-               case OPT_LSRA:
-#if defined(__I386__) || defined(__ALPHA__) || defined (__X86_64__) || defined(__POWERPC__)
-                       opt_lsra = true;
-#else
-                       printf("LSRA not available for this architecture\n");
-                       opt_lsra = false;
-#endif
-                       break;
-#endif
-
-               default:
-                       printf("Unknown option: %s\n", argv[opt_ind]);
-                       usage();
-               }
-       }
-
-       if (opt_ind >= argc)
-               usage();
-
-
-       /* transform dots into slashes in the class name */
-
-       mainstring = argv[opt_ind++];
-       if (!jar) { 
-        /* do not mangle jar filename */
-               for (i = strlen(mainstring) - 1; i >= 0; i--) {
-                       if (mainstring[i] == '.') mainstring[i] = '/';
-               }
+       if (atexit(vm_exit_handler))
+               throw_cacao_exception_exit(string_java_lang_InternalError,
+                                                                  "Unable to register exit_handler");
 
-       } else {
-               /* put jarfile in classpath */
-               cp = classpath;
-               classpath = MNEW(char, strlen(mainstring) + 1 + strlen(classpath) + 1);
-               strcpy(classpath, mainstring);
-               strcat(classpath, ":");
-               strcat(classpath, cp);
-               
-               MFREE(cp, char, strlen(cp));
-       }
 
        /**************************** Program start *****************************/
 
-       log_init(logfilename);
-
        if (opt_verbose)
                log_text("CACAO started -------------------------------------------------------");
 
-       /* initialize JavaVM */
-
-       vm_args.version = 0x00010001; /* New in 1.1.2: VM version */
-
-       /* Get the default initialization arguments and set the class path */
-
-       JNI_GetDefaultJavaVMInitArgs(&vm_args);
-
-       vm_args.minHeapSize = heapstartsize;
-       vm_args.maxHeapSize = heapmaxsize;
+       /* prepare the options */
 
-       vm_args.classpath = classpath;
+       vm_args = options_prepare(argc, argv);
+       
        /* load and initialize a Java VM, return a JNI interface pointer in env */
 
-       JNI_CreateJavaVM(&jvm, &env, &vm_args);
-
-
-       /* initialize the garbage collector */
-
-       gc_init(heapmaxsize, heapstartsize);
-
-       tables_init();
-
-       /* initialize the loader with bootclasspath */
-
-       suck_init(bootclasspath);
-
-       cacao_initializing = true;
+       JNI_CreateJavaVM(&jvm, (void *) &_Jv_env, vm_args);
 
-#if defined(USE_THREADS)
-#if defined(NATIVE_THREADS)
-       initThreadsEarly();
+#if defined(ENABLE_JVMTI)
+       pthread_mutex_init(&dbgcomlock,NULL);
+       if (jvmti) jvmti_set_phase(JVMTI_PHASE_START);
 #endif
-       initLocks();
-#endif
-
-       /* install architecture dependent signal handler used for exceptions */
-       init_exceptions();
-
-       /* initializes jit compiler and codegen stuff */
-       jit_init();
-
-       /* initialize some cacao subsystems */
-
-       utf8_init();
-
-       if (!loader_init((u1 *) &dummy))
-               throw_main_exception_exit();
-
-       if (!linker_init())
-               throw_main_exception_exit();
-
-       if (!native_init())
-               throw_main_exception_exit();
-
-       if (!exceptions_init())
-               throw_main_exception_exit();
-
-#if defined(USE_THREADS)
-       initThreads((u1 *) &dummy);
-#endif
-
-       *threadrootmethod = NULL;
 
-       /*That's important, otherwise we get into trouble, if the Runtime static
-         initializer is called before (circular dependency. This is with
-         classpath 0.09. Another important thing is, that this has to happen
-         after initThreads!!! */
+       /* do we have a main class? */
 
-       if (!class_init(class_java_lang_System))
-               throw_main_exception_exit();
-
-       cacao_initializing = false;
+       if (mainstring == NULL)
+               usage();
 
 
        /* start worker routines **************************************************/
 
-       if (startit) {
-               classinfo        *cl;           /* java/lang/ClassLoader              */
-               classinfo        *mainclass;    /* java/lang/Class                    */
+       if (opt_run == true) {
+               utf              *mainutf;
+               classinfo        *mainclass;
                methodinfo       *m;
-               java_objectarray *a; 
+               java_objectarray *oa; 
+               s4                oalength;
+               java_lang_String *s;
                s4                status;
 
                /* set return value to OK */
 
                status = 0;
 
-               if (jar) {
+               if (opt_jar == true) {
                        /* open jar file with java.util.jar.JarFile */
-                       mainstring = getmainclassnamefromjar((JNIEnv *) &env, mainstring);
+                       mainstring = getmainclassnamefromjar(mainstring);
                }
 
                /* load the main class */
 
-               if (!load_class_from_sysloader(utf_new_char(mainstring),&mainclass))
+               mainutf = utf_new_char(mainstring);
+
+               if (!(mainclass = load_class_from_sysloader(mainutf)))
                        throw_main_exception_exit();
 
                /* error loading class, clear exceptionptr for new exception */
@@ -936,6 +264,9 @@ int main(int argc, char **argv)
                        throw_main_exception_exit();
                }
 
+               if (!link_class(mainclass))
+                       throw_main_exception_exit();
+                       
                /* find the `main' method of the main class */
 
                m = class_resolveclassmethod(mainclass,
@@ -944,9 +275,13 @@ int main(int argc, char **argv)
                                                                         class_java_lang_Object,
                                                                         false);
 
+               if (*exceptionptr) {
+                       throw_main_exception_exit();
+               }
+
                /* there is no main method or it isn't static */
 
-               if (*exceptionptr || !m || !(m->flags & ACC_STATIC)) {
+               if (!m || !(m->flags & ACC_STATIC)) {
                        *exceptionptr = NULL;
 
                        *exceptionptr =
@@ -957,10 +292,13 @@ int main(int argc, char **argv)
 
                /* build argument array */
 
-               a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
-               for (i = opt_ind; i < argc; i++) {
-                       a->data[i - opt_ind] = 
-                               (java_objectheader *) javastring_new(utf_new_char(argv[i]));
+               oalength = vm_args->nOptions - opt_index;
+
+               oa = builtin_anewarray(oalength, class_java_lang_String);
+
+               for (i = 0; i < oalength; i++) {
+                       s = javastring_new(utf_new_char(vm_args->options[opt_index + i].optionString));
+                       oa->data[i] = (java_objectheader *) s;
                }
 
 #ifdef TYPEINFO_DEBUG_TEST
@@ -969,35 +307,32 @@ int main(int argc, char **argv)
 #endif
                /*class_showmethods(currentThread->group->header.vftbl->class); */
 
-               *threadrootmethod = m;
-
-               /* here we go... */
+#if defined(ENABLE_JVMTI)
+               jvmti_set_phase(JVMTI_PHASE_LIVE);
+#endif
 
-               asm_calljavafunction(m, a, NULL, NULL, NULL);
+               (void) vm_call_method(m, NULL, oa);
 
                /* exception occurred? */
+
                if (*exceptionptr) {
                        throw_main_exception();
                        status = 1;
                }
 
-#if defined(USE_THREADS)
-#if defined(NATIVE_THREADS)
-               joinAllThreads();
-#else
-               killThread(currentThread);
-#endif
-#endif
+               /* unload the JavaVM */
 
-               /* now exit the JavaVM */
+               vm_destroy(jvm);
 
-/*             (*jvm)->DestroyJavaVM(jvm); */
+               /* and exit */
 
-               cacao_exit(status);
+               vm_exit(status);
        }
 
-       /************* If requested, compile all methods ********************/
 
+       /* If requested, compile all methods. *************************************/
+
+#if !defined(NDEBUG)
        if (compileall) {
                classinfo *c;
                methodinfo *m;
@@ -1005,65 +340,92 @@ int main(int argc, char **argv)
                s4 i;
                classcache_name_entry *nmen;
                classcache_class_entry *clsen;
-               classcache_loader_entry *lden;
 
-               /* create all classes found in the classpath */
+               /* create all classes found in the bootclasspath */
                /* XXX currently only works with zip/jar's */
-               create_all_classes();
+
+               loader_load_all_classes();
 
                /* link all classes */
-               for (slot=0; slot<classcache_hash.size; ++slot) {
-                       nmen = (classcache_name_entry *) classcache_hash.ptr[slot];
-                       for (; nmen; nmen=nmen->hashlink) {
+
+               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) {
+
+                               for (clsen = nmen->classes; clsen; clsen = clsen->next) {
                                        c = clsen->classobj;
+
                                        if (!c)
                                                continue;
 
-                                       assert(c);
-                                       assert(c->loaded);
-                                       /*utf_fprint_classname(stderr,c->name);fprintf(stderr,"\n");*/
+                                       if (!(c->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_exception(*exceptionptr);
 
-                                       if (!c->linked)
-                                               if (!link_class(c))
-                                                       throw_main_exception_exit();
+                                                       /* goto next class */
+
+                                                       continue;
+                                               }
+                                       }
 
                                        /* compile all class methods */
+
                                        for (i = 0; i < c->methodscount; i++) {
                                                m = &(c->methods[i]);
+
                                                if (m->jcode) {
-                                                       /*fprintf(stderr,"    compiling:");utf_fprint(stderr,m->name);fprintf(stderr,"\n");*/
-                                                       (void) jit_compile(m);
+                                                       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_exception(*exceptionptr);
+                                                       }
                                                }
                                        }
                                }
                        }
                }
        }
+#endif /* !defined(NDEBUG) */
 
 
-       /******** If requested, compile a specific method ***************/
+       /* If requested, compile a specific method. *******************************/
 
-       if (specificmethodname) {
+#if !defined(NDEBUG)
+       if (opt_method != NULL) {
                methodinfo *m;
 
                /* create, load and link the main class */
-               if (!load_class_from_sysloader(utf_new_char(mainstring),&mainclass))
+
+               if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
                        throw_main_exception_exit();
 
                if (!link_class(mainclass))
                        throw_main_exception_exit();
 
-               if (specificsignature) {
+               if (opt_signature != NULL) {
                        m = class_resolveclassmethod(mainclass,
-                                                                                utf_new_char(specificmethodname),
-                                                                                utf_new_char(specificsignature),
+                                                                                utf_new_char(opt_method),
+                                                                                utf_new_char(opt_signature),
                                                                                 mainclass,
                                                                                 false);
                } else {
                        m = class_resolveclassmethod(mainclass,
-                                                                                utf_new_char(specificmethodname),
+                                                                                utf_new_char(opt_method),
                                                                                 NULL,
                                                                                 mainclass,
                                                                                 false);
@@ -1071,8 +433,8 @@ int main(int argc, char **argv)
 
                if (!m) {
                        char message[MAXLOGTEXT];
-                       sprintf(message, "%s%s", specificmethodname,
-                                       specificsignature ? specificsignature : "");
+                       sprintf(message, "%s%s", opt_method,
+                                       opt_signature ? opt_signature : "");
 
                        *exceptionptr =
                                new_exception_message(string_java_lang_NoSuchMethodException,
@@ -1084,7 +446,8 @@ int main(int argc, char **argv)
                jit_compile(m);
        }
 
-       cacao_shutdown(0);
+       vm_shutdown(0);
+#endif /* !defined(NDEBUG) */
 
        /* keep compiler happy */
 
@@ -1092,69 +455,6 @@ int main(int argc, char **argv)
 }
 
 
-/* cacao_exit ******************************************************************
-
-   Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
-
-*******************************************************************************/
-
-void cacao_exit(s4 status)
-{
-       methodinfo *m;
-
-       assert(class_java_lang_System);
-       assert(class_java_lang_System->loaded);
-
-       if (!link_class(class_java_lang_System))
-               throw_main_exception_exit();
-
-       /* 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)
-               throw_main_exception_exit();
-
-       /* call the exit function with passed exit status */
-
-       /* both inlinevirtual and outsiders not allowed on exit */
-       /*   not sure if permanant or temp restriction          */
-       if (inlinevirtuals) inlineoutsiders = false; 
-
-       asm_calljavafunction(m, (void *) (ptrint) status, NULL, NULL, NULL);
-
-       /* this should never happen */
-
-       if (*exceptionptr)
-               throw_exception_exit();
-
-       throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                          "System.exit(I)V returned without exception");
-}
-
-
-/*************************** Shutdown function *********************************
-
-       Terminates the system immediately without freeing memory explicitly (to be
-       used only for abnormal termination)
-       
-*******************************************************************************/
-
-void cacao_shutdown(s4 status)
-{
-       if (opt_verbose || getcompilingtime || opt_stat) {
-               log_text("CACAO terminated by shutdown");
-               dolog("Exit status: %d\n", (s4) status);
-       }
-
-       exit(status);
-}
-
-
 /*
  * 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