GNU header update.
[cacao.git] / src / cacao / cacao.c
index 40127052c40825d36b6e51ba0a9666cdb2aff9e2..f989db7f183db8776c3634fb422f9953e5b5de6f 100644 (file)
@@ -1,10 +1,9 @@
-/* main.c - contains main() and variables for the global options
+/* cacao/cacao.c - contains main() of cacao
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   Institut f. Computersprachen, TU Wien
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
-   S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
-   J. Wenninger
+   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
 
    This file is part of CACAO.
 
      - Calling the class loader
      - Running the main method
 
-   $Id: cacao.c 1359 2004-07-28 10:48:36Z twisti $
+   $Id: cacao.c 1735 2004-12-07 14:33:27Z twisti $
 
 */
 
 
 #include <stdlib.h>
 #include <string.h>
-#include "exceptions.h"
-#include "main.h"
-#include "options.h"
-#include "global.h"
-#include "tables.h"
-#include "loader.h"
-#include "jit/jit.h"
-#include "asmpart.h"
-#include "builtin.h"
-#include "native.h"
-#include "statistics.h"
+
+#include "cacao/cacao.h"
 #include "mm/boehm.h"
-#include "threads/thread.h"
+#include "mm/memory.h"
+#include "native/native.h"
 #include "toolbox/logging.h"
-#include "toolbox/memory.h"
-#include "jit/parseRTstats.h"
-#include "nat/java_io_File.h"            /* required by java_lang_Runtime.h   */
-#include "nat/java_util_Properties.h"    /* required by java_lang_Runtime.h   */
-#include "nat/java_lang_Runtime.h"
-#include "nat/java_lang_Throwable.h"
+#include "vm/exceptions.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/statistics.h"
+#include "vm/tables.h"
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
 
 #ifdef TYPEINFO_DEBUG_TEST
 #include "typeinfo.h"
@@ -80,16 +73,7 @@ static classinfo *mainclass;
 void **stackbottom = 0;
 #endif
 
-
-/* internal function: get_opt *************************************************
-       
-       decodes the next command line option
-       
-******************************************************************************/
-
-#define OPT_DONE       -1
-#define OPT_ERROR       0
-#define OPT_IGNORE      1
+/* define command line options ************************************************/
 
 #define OPT_CLASSPATH   2
 #define OPT_D           3
@@ -112,17 +96,21 @@ void **stackbottom = 0;
 #define OPT_ALL         20
 #define OPT_OLOOP       24
 #define OPT_INLINING   25
+#ifdef STATIC_ANALYSIS
 #define OPT_RT          26
 #define OPT_XTA         27 
 #define OPT_VTA         28
+#endif
 #define OPT_VERBOSETC   29
 #define OPT_NOVERIFY    30
 #define OPT_LIBERALUTF  31
 #define OPT_VERBOSEEXCEPTION 32
 #define OPT_EAGER            33
+#ifdef LSRA
+#define OPT_LSRA 34
+#endif
 
-
-struct {char *name; bool arg; int value;} opts[] = {
+opt_struct opts[] = {
        {"classpath",        true,   OPT_CLASSPATH},
        {"cp",               true,   OPT_CLASSPATH},
        {"D",                true,   OPT_D},
@@ -159,59 +147,17 @@ struct {char *name; bool arg; int value;} opts[] = {
        {"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},
+#endif
        {NULL,               false,  0}
 };
 
-static int opt_ind = 1;
-static char *opt_arg;
-
-
-static int get_opt(int argc, char **argv)
-{
-       char *a;
-       int i;
-       
-       if (opt_ind >= argc) return OPT_DONE;
-       
-       a = argv[opt_ind];
-       if (a[0] != '-') return OPT_DONE;
-
-       for (i = 0; opts[i].name; i++) {
-               if (!opts[i].arg) {
-                       if (strcmp(a + 1, opts[i].name) == 0) { /* boolean option found */
-                               opt_ind++;
-                               return opts[i].value;
-                       }
-
-               } else {
-                       if (strcmp(a + 1, opts[i].name) == 0) { /* parameter option found */
-                               opt_ind++;
-                               if (opt_ind < argc) {
-                                       opt_arg = argv[opt_ind];
-                                       opt_ind++;
-                                       return opts[i].value;
-                               }
-                               return OPT_ERROR;
-
-                       } else {
-                               size_t l = strlen(opts[i].name);
-                               if (strlen(a + 1) > l) {
-                                       if (memcmp(a + 1, opts[i].name, l) == 0) {
-                                               opt_ind++;
-                                               opt_arg = a + 1 + l;
-                                               return opts[i].value;
-                                       }
-                               }
-                       }
-               }
-       } /* end for */ 
-
-       return OPT_ERROR;
-}
-
 
 /******************** interne Function: print_usage ************************
 
@@ -219,7 +165,7 @@ Prints the correct usage syntax to stdout.
 
 ***************************************************************************/
 
-static void print_usage()
+static void usage()
 {
        printf("USAGE: cacao [options] classname [program arguments]\n");
        printf("Options:\n");
@@ -263,12 +209,22 @@ static void print_usage()
        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 */
+
+       exit(1);
 }   
 
 
@@ -303,7 +259,7 @@ void exit_handler(void)
 
        MFREE(classpath, u1, strlen(classpath));
 
-       if (verbose || getcompilingtime || opt_stat) {
+       if (opt_verbose || getcompilingtime || opt_stat) {
                log_text("CACAO terminated");
                if (opt_stat) {
                        print_stats();
@@ -335,6 +291,7 @@ int main(int argc, char **argv)
        u4 heapmaxsize = 64 * 1024 * 1024;
        u4 heapstartsize = 200 * 1024;
        char *cp;
+       s4    cplen;
        bool startit = true;
        char *specificmethodname = NULL;
        char *specificsignature = NULL;
@@ -350,18 +307,19 @@ int main(int argc, char **argv)
 
        /************ Collect info from the environment ************************/
 
-       classpath = MNEW(u1, 2);
+       /* set an initial, minimal classpath */
+       classpath = MNEW(char, 2);
        strcpy(classpath, ".");
 
        /* get classpath environment */
        cp = getenv("CLASSPATH");
        if (cp) {
                classpath = MREALLOC(classpath,
-                                                        u1,
+                                                        char,
                                                         strlen(classpath),
                                                         strlen(classpath) + 1 + strlen(cp) + 1);
                strcat(classpath, ":");
-               strncat(classpath, cp, strlen(cp));
+               strcat(classpath, cp);
        }
 
        /***************** Interpret the command line *****************/
@@ -369,17 +327,17 @@ int main(int argc, char **argv)
        checknull = false;
        opt_noieee = false;
 
-       while ((i = get_opt(argc, argv)) != OPT_DONE) {
+       while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
                switch (i) {
-               case OPT_IGNORE: break;
+               case OPT_IGNORE:
+                       break;
                        
                case OPT_CLASSPATH:
-                       classpath = MREALLOC(classpath,
-                                                                u1,
-                                                                strlen(classpath),
-                                                                strlen(classpath) + 1 + strlen(opt_arg) + 1);
-                       strcat(classpath, ":");
-                       strncat(classpath, opt_arg, strlen(opt_arg));
+                       /* 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_D:
@@ -389,12 +347,11 @@ int main(int argc, char **argv)
                                for (n = 0; n < l; n++) {
                                        if (opt_arg[n] == '=') {
                                                opt_arg[n] = '\0';
-                                               attach_property(opt_arg, opt_arg + n + 1);
+                                               create_property(opt_arg, opt_arg + n + 1);
                                                goto didit;
                                        }
                                }
-                               print_usage();
-                               exit(10);
+                               usage();
                                        
                        didit: ;
                        }       
@@ -420,11 +377,11 @@ int main(int argc, char **argv)
                        break;
 
                case OPT_VERBOSE1:
-                       verbose = true;
+                       opt_verbose = true;
                        break;
 
                case OPT_VERBOSE:
-                       verbose = true;
+                       opt_verbose = true;
                        loadverbose = true;
                        linkverbose = true;
                        initverbose = true;
@@ -488,8 +445,7 @@ int main(int argc, char **argv)
                                        checksync = false;
                                        break;
                                default:
-                                       print_usage();
-                                       exit(10);
+                                       usage();
                                }
                        }
                        break;
@@ -543,8 +499,7 @@ int main(int argc, char **argv)
                                        showutf = true;
                                        break;
                                default:
-                                       print_usage();
-                                       exit(10);
+                                       usage();
                                }
                        }
                        break;
@@ -557,10 +512,17 @@ int main(int argc, char **argv)
                        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;
@@ -572,12 +534,12 @@ int main(int argc, char **argv)
                                        inlineoutsiders = true;
                                        break;
                                default:
-                                       print_usage();
-                                       exit(10);
+                                       usage();
                                }
                        }
                        break;
 
+#ifdef STATIC_ANALYSIS
                case OPT_RT:
                        opt_rt = true;
                        break;
@@ -589,29 +551,53 @@ int main(int argc, char **argv)
                case OPT_VTA:
                        /***opt_vta = true; not yet **/
                        break;
+#endif
+
+#ifdef LSRA
+               case OPT_LSRA:
+#if defined(__I386__) || defined(__ALPHA__)
+                       opt_lsra = true;
+#else
+                       printf("LSRA not available for this architecture\n");
+                       opt_lsra = false;
+#endif
+                       break;
+#endif
 
                default:
-                       print_usage();
-                       exit(10);
+                       usage();
                }
        }
-   
-   
-       if (opt_ind >= argc) {
-               print_usage();
-               exit(10);
-       }
+
+       if (opt_ind >= argc)
+               usage();
+
+
+       /* insert the rt.jar in front of all other classpath entries */
+
+       cplen = strlen(INSTALL_PREFIX) + strlen(CACAO_RT_JAR_PATH);
+       cp = classpath;
+
+       classpath = MNEW(char, cplen + strlen(classpath) + 1);
+       strcpy(classpath, INSTALL_PREFIX);
+       strcat(classpath, CACAO_RT_JAR_PATH);
+       strcat(classpath, cp);
+
+       MFREE(cp, char, strlen(cp));
+
+
+       /* transform dots into slashes in the class name */
 
        mainstring = argv[opt_ind++];
-       for (i = strlen(mainstring) - 1; i >= 0; i--) {     /* Transform dots into slashes */
-               if (mainstring[i] == '.') mainstring[i] = '/';  /* in the class name */
+       for (i = strlen(mainstring) - 1; i >= 0; i--) {
+               if (mainstring[i] == '.') mainstring[i] = '/';
        }
 
 
        /**************************** Program start *****************************/
 
        log_init(logfilename);
-       if (verbose)
+       if (opt_verbose)
                log_text("CACAO started -------------------------------------------------------");
 
        /* initialize the garbage collector */
@@ -622,9 +608,12 @@ int main(int argc, char **argv)
 
        cacao_initializing = true;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(USE_THREADS)
+#if defined(NATIVE_THREADS)
        initThreadsEarly();
 #endif
+       initLocks();
+#endif
 
        /* install architecture dependent signal handler used for exceptions */
        init_exceptions();
@@ -634,10 +623,9 @@ int main(int argc, char **argv)
 
        loader_init((u1 *) &dummy);
 
-       jit_init();
-
        /* initialize exceptions used in the system */
-       init_system_exceptions();
+       if (!init_system_exceptions())
+               throw_main_exception_exit();
 
        native_loadclasses();
 
@@ -655,6 +643,9 @@ int main(int argc, char **argv)
        if (!class_init(class_new(utf_new_char("java/lang/System"))))
                throw_main_exception_exit();
 
+       
+       
+/*        jni_init(); */
        cacao_initializing = false;
 
        /************************* Start worker routines ********************/
@@ -662,6 +653,10 @@ int main(int argc, char **argv)
        if (startit) {
                methodinfo *mainmethod;
                java_objectarray *a; 
+               s4 status;
+
+               /* set return value to OK */
+               status = 0;
 
                /* create, load and link the main class */
                mainclass = class_new(utf_new_char(mainstring));
@@ -709,8 +704,10 @@ int main(int argc, char **argv)
                asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
 
                /* exception occurred? */
-               if (*exceptionptr)
+               if (*exceptionptr) {
                        throw_main_exception();
+                       status = 1;
+               }
 
 #if defined(USE_THREADS)
 #if defined(NATIVE_THREADS)
@@ -722,7 +719,7 @@ int main(int argc, char **argv)
 
                /* now exit the JavaVM */
 
-               cacao_exit(0);
+               cacao_exit(status);
        }
 
        /************* If requested, compile all methods ********************/
@@ -825,11 +822,10 @@ void cacao_exit(s4 status)
 {
        classinfo *c;
        methodinfo *m;
-       java_lang_Runtime *rt;
 
        /* class should already be loaded, but who knows... */
 
-       c = class_new(utf_new_char("java/lang/Runtime"));
+       c = class_new(utf_new_char("java/lang/System"));
 
        if (!class_load(c))
                throw_main_exception_exit();
@@ -837,29 +833,7 @@ void cacao_exit(s4 status)
        if (!class_link(c))
                throw_main_exception_exit();
 
-       /* first call Runtime.getRuntime()Ljava.lang.Runtime; */
-
-       m = class_resolveclassmethod(c,
-                                                                utf_new_char("getRuntime"),
-                                                                utf_new_char("()Ljava/lang/Runtime;"),
-                                                                class_java_lang_Object,
-                                                                true);
-
-       if (!m)
-               throw_main_exception_exit();
-
-       rt = (java_lang_Runtime *) asm_calljavafunction(m,
-                                                                                                       (void *) 0,
-                                                                                                       NULL,
-                                                                                                       NULL,
-                                                                                                       NULL);
-
-       /* exception occurred? */
-
-       if (*exceptionptr)
-               throw_main_exception_exit();
-
-       /* then call Runtime.exit(I)V */
+       /* call System.exit(I)V */
 
        m = class_resolveclassmethod(c,
                                                                 utf_new_char("exit"),
@@ -870,12 +844,25 @@ void cacao_exit(s4 status)
        if (!m)
                throw_main_exception_exit();
 
-       asm_calljavafunction(m, rt, (void *) 0, NULL, NULL);
+       /* call the exit function with passed exit status */
+
+       asm_calljavafunction(m,
+#if POINTERSIZE == 8
+                                                (void *) (s8) status,
+#else
+                                                (void *) status,
+#endif
+                                                NULL,
+                                                NULL,
+                                                NULL);
 
        /* this should never happen */
 
+       if (*exceptionptr)
+               throw_exception_exit();
+
        throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                          "Problems with Runtime.exit(I)V");
+                                                          "System.exit(I)V returned without exception");
 }
 
 
@@ -888,16 +875,9 @@ void cacao_exit(s4 status)
 
 void cacao_shutdown(s4 status)
 {
-       /**** RTAprint ***/
-
-       if (verbose || getcompilingtime || opt_stat) {
+       if (opt_verbose || getcompilingtime || opt_stat) {
                log_text("CACAO terminated by shutdown");
-               if (opt_stat)
-                       print_stats();
-               if (getcompilingtime)
-                       print_times();
-               mem_usagelog(0);
-               dolog("Exit status: %d\n", (int) status);
+               dolog("Exit status: %d\n", (s4) status);
        }
 
        exit(status);