X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fcacao%2Fcacao.c;h=f989db7f183db8776c3634fb422f9953e5b5de6f;hb=d75b6037acf17c342166b9c9bd6e657dfdd12cd9;hp=069a050686e3c7eb62a9445e8755ae2cc43adfbe;hpb=c0c0a21bf39477528d21d137bac4e0f7fea1a7bd;p=cacao.git diff --git a/src/cacao/cacao.c b/src/cacao/cacao.c index 069a05068..f989db7f1 100644 --- a/src/cacao/cacao.c +++ b/src/cacao/cacao.c @@ -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. @@ -37,98 +36,44 @@ - Calling the class loader - Running the main method - $Id: cacao.c 861 2004-01-06 20:55:56Z twisti $ + $Id: cacao.c 1735 2004-12-07 14:33:27Z twisti $ */ #include #include -#include "main.h" -#include "global.h" -#include "tables.h" -#include "loader.h" -#include "jit.h" -#include "asmpart.h" -#include "builtin.h" -#include "native.h" -#include "mm/boehm.h" -#include "threads/thread.h" -#include "toolbox/loging.h" -#include "toolbox/memory.h" -#include "parseRTstats.h" -#include "typeinfo.h" /* XXX remove debug */ -#include "nat/java_lang_Throwable.h" - - -/* command line option */ - -bool verbose = false; -bool compileall = false; -bool runverbose = false; /* trace all method invocation */ -bool collectverbose = false; - -bool loadverbose = false; -bool linkverbose = false; -bool initverbose = false; - -bool opt_rt = false; /* true if RTA parse should be used RT-CO */ -bool opt_xta = false; /* true if XTA parse should be used XTA-CO */ -bool opt_vta = false; /* true if VTA parse should be used VTA-CO */ - -bool showmethods = false; -bool showconstantpool = false; -bool showutf = false; - -bool compileverbose = false; /* trace compiler actions */ -bool showstack = false; -bool showdisassemble = false; /* generate disassembler listing */ -bool showddatasegment = false; /* generate data segment listing */ -bool showintermediate = false; /* generate intermediate code listing */ - -bool useinlining = false; /* use method inlining */ -bool inlinevirtuals = false; /* inline unique virtual methods */ -bool inlineexceptions = false; /* inline methods, that contain excptions */ -bool inlineparamopt = false; /* optimize parameter passing to inlined methods */ -bool inlineoutsiders = false; /* inline methods, that are not member of the invoker's class */ - -bool checkbounds = true; /* check array bounds */ -bool checknull = true; /* check null pointers */ -bool opt_noieee = false; /* don't implement ieee compliant floats */ -bool checksync = true; /* do synchronization */ -bool opt_loops = false; /* optimize array accesses in loops */ - -bool makeinitializations = true; - -bool getloadingtime = false; /* to measure the runtime */ -s8 loadingtime = 0; - -bool getcompilingtime = false; /* compute compile time */ -s8 compilingtime = 0; /* accumulated compile time */ -int has_ext_instr_set = 0; /* has instruction set extensions */ +#include "cacao/cacao.h" +#include "mm/boehm.h" +#include "mm/memory.h" +#include "native/native.h" +#include "toolbox/logging.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" -bool statistics = false; +#ifdef TYPEINFO_DEBUG_TEST +#include "typeinfo.h" +#endif -bool opt_verify = true; /* true if classfiles should be verified */ +bool cacao_initializing; -static classinfo *topclass; +char *classpath; /* contains classpath */ +char *mainstring; +static classinfo *mainclass; -#ifndef USE_THREADS +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) 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 @@ -151,99 +96,68 @@ 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[] = { - {"classpath", true, OPT_CLASSPATH}, - {"D", true, OPT_D}, - {"ms", true, OPT_MS}, - {"mx", true, OPT_MX}, - {"noasyncgc", false, OPT_IGNORE}, - {"noverify", false, OPT_NOVERIFY}, - {"oss", true, OPT_IGNORE}, - {"ss", true, OPT_IGNORE}, - {"v", false, OPT_VERBOSE1}, - {"verbose", false, OPT_VERBOSE}, - {"verbosegc", false, OPT_VERBOSEGC}, - {"verbosecall", false, OPT_VERBOSECALL}, +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}, + {"verbosetc", false, OPT_VERBOSETC}, #endif #if defined(__ALPHA__) - {"noieee", false, OPT_NOIEEE}, + {"noieee", false, OPT_NOIEEE}, #endif - {"softnull", false, OPT_SOFTNULL}, - {"time", false, OPT_TIME}, - {"stat", false, OPT_STAT}, - {"log", true, OPT_LOG}, - {"c", true, OPT_CHECK}, - {"l", false, OPT_LOAD}, - {"m", true, OPT_METHOD}, - {"sig", true, OPT_SIGNATURE}, - {"s", true, OPT_SHOW}, - {"all", false, OPT_ALL}, - {"oloop", false, OPT_OLOOP}, - {"i", true, OPT_INLINING}, - {"rt", false, OPT_RT}, - {"xta", false, OPT_XTA}, - {"vta", false, OPT_VTA}, - {NULL, false, 0} + {"softnull", false, OPT_SOFTNULL}, + {"time", false, OPT_TIME}, + {"stat", false, OPT_STAT}, + {"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}, +#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 ************************ @@ -251,18 +165,22 @@ 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"); + printf(" -cp path ............. specify a path to look for classes\n"); printf(" -classpath path ...... specify a path to look for classes\n"); printf(" -Dpropertyname=value . add an entry to the property list\n"); - printf(" -mx maxmem[k|m] ...... specify the size for the heap\n"); - printf(" -ms initmem[k|m] ..... specify the initial size for the heap\n"); + printf(" -Xmx maxmem[kK|mM] ... specify the size for the heap\n"); + printf(" -Xms initmem[kK|mM] .. specify the initial size for the heap\n"); + printf(" -mx maxmem[kK|mM] .... specify the size for the heap\n"); + printf(" -ms initmem[kK|mM] ... specify the initial size for the heap\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 @@ -270,6 +188,7 @@ static void print_usage() 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"); printf(" -stat ................ detailed compiler statistics\n"); @@ -278,6 +197,7 @@ static void print_usage() 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"); @@ -289,258 +209,28 @@ 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"); -} - - - -/***************************** Function: print_times ********************* - - Prints a summary of CPU time usage. - -**************************************************************************/ - -static void print_times() -{ - s8 totaltime = getcputime(); - s8 runtime = totaltime - loadingtime - compilingtime; - char logtext[MAXLOGTEXT]; - -#if defined(__I386__) - sprintf(logtext, "Time for loading classes: %lld secs, %lld millis", -#else - sprintf(logtext, "Time for loading classes: %ld secs, %ld millis", #endif - loadingtime / 1000000, (loadingtime % 1000000) / 1000); - log_text(logtext); - -#if defined(__I386__) - sprintf(logtext, "Time for compiling code: %lld secs, %lld millis", -#else - sprintf(logtext, "Time for compiling code: %ld secs, %ld millis", +#ifdef LSRA + printf(" -lsra ................ use linear scan register allocation\n"); #endif - compilingtime / 1000000, (compilingtime % 1000000) / 1000); - log_text(logtext); - -#if defined(__I386__) - sprintf(logtext, "Time for running program: %lld secs, %lld millis", -#else - sprintf(logtext, "Time for running program: %ld secs, %ld millis", -#endif - runtime / 1000000, (runtime % 1000000) / 1000); - log_text(logtext); - -#if defined(__I386__) - sprintf(logtext, "Total time: %lld secs, %lld millis", -#else - sprintf(logtext, "Total time: %ld secs, %ld millis", -#endif - totaltime / 1000000, (totaltime % 1000000) / 1000); - log_text(logtext); -} - + /* exit with error code */ + exit(1); +} - -/***************************** Function: print_stats ********************* - - outputs detailed compiler statistics - -**************************************************************************/ - -static void print_stats() -{ - char logtext[MAXLOGTEXT]; - - sprintf(logtext, "Number of JitCompiler Calls: %d", count_jit_calls); - log_text(logtext); - sprintf(logtext, "Number of compiled Methods: %d", count_methods); - log_text(logtext); - sprintf(logtext, "Number of max basic blocks per method: %d", count_max_basic_blocks); - log_text(logtext); - sprintf(logtext, "Number of compiled basic blocks: %d", count_basic_blocks); - log_text(logtext); - sprintf(logtext, "Number of max JavaVM-Instructions per method: %d", count_max_javainstr); - log_text(logtext); - sprintf(logtext, "Number of compiled JavaVM-Instructions: %d", count_javainstr); - log_text(logtext); - sprintf(logtext, "Size of compiled JavaVM-Instructions: %d(%d)", count_javacodesize, - count_javacodesize - count_methods * 18); - log_text(logtext); - sprintf(logtext, "Size of compiled Exception Tables: %d", count_javaexcsize); - log_text(logtext); - sprintf(logtext, "Value of extended instruction set var: %d", has_ext_instr_set); - log_text(logtext); - sprintf(logtext, "Number of Machine-Instructions: %d", count_code_len >> 2); - log_text(logtext); - sprintf(logtext, "Number of Spills: %d", count_spills); - log_text(logtext); - sprintf(logtext, "Number of Activ Pseudocommands: %5d", count_pcmd_activ); - log_text(logtext); - sprintf(logtext, "Number of Drop Pseudocommands: %5d", count_pcmd_drop); - log_text(logtext); - sprintf(logtext, "Number of Const Pseudocommands: %5d (zero:%5d)", count_pcmd_load, count_pcmd_zero); - log_text(logtext); - sprintf(logtext, "Number of ConstAlu Pseudocommands: %5d (cmp: %5d, store:%5d)", count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store); - log_text(logtext); - sprintf(logtext, "Number of Move Pseudocommands: %5d", count_pcmd_move); - log_text(logtext); - sprintf(logtext, "Number of Load Pseudocommands: %5d", count_load_instruction); - log_text(logtext); - sprintf(logtext, "Number of Store Pseudocommands: %5d (combined: %5d)", count_pcmd_store, count_pcmd_store - count_pcmd_store_comb); - log_text(logtext); - sprintf(logtext, "Number of OP Pseudocommands: %5d", count_pcmd_op); - log_text(logtext); - sprintf(logtext, "Number of DUP Pseudocommands: %5d", count_dup_instruction); - log_text(logtext); - sprintf(logtext, "Number of Mem Pseudocommands: %5d", count_pcmd_mem); - log_text(logtext); - sprintf(logtext, "Number of Method Pseudocommands: %5d", count_pcmd_met); - log_text(logtext); - sprintf(logtext, "Number of Branch Pseudocommands: %5d (rets:%5d, Xrets: %5d)", - count_pcmd_bra, count_pcmd_return, count_pcmd_returnx); - log_text(logtext); - sprintf(logtext, "Number of Table Pseudocommands: %5d", count_pcmd_table); - log_text(logtext); - sprintf(logtext, "Number of Useful Pseudocommands: %5d", count_pcmd_table + - count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op); - log_text(logtext); - sprintf(logtext, "Number of Null Pointer Checks: %5d", count_check_null); - log_text(logtext); - sprintf(logtext, "Number of Array Bound Checks: %5d", count_check_bound); - log_text(logtext); - sprintf(logtext, "Number of Try-Blocks: %d", count_tryblocks); - log_text(logtext); - sprintf(logtext, "Maximal count of stack elements: %d", count_max_new_stack); - log_text(logtext); - sprintf(logtext, "Upper bound of max stack elements: %d", count_upper_bound_new_stack); - log_text(logtext); - sprintf(logtext, "Distribution of stack sizes at block boundary"); - log_text(logtext); - sprintf(logtext, " 0 1 2 3 4 5 6 7 8 9 >=10"); - log_text(logtext); - sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", 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]); - log_text(logtext); - sprintf(logtext, "Distribution of store stack depth"); - log_text(logtext); - sprintf(logtext, " 0 1 2 3 4 5 6 7 8 9 >=10"); - log_text(logtext); - sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", 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]); - log_text(logtext); - sprintf(logtext, "Distribution of store creator chains first part"); - log_text(logtext); - sprintf(logtext, " 0 1 2 3 4 5 6 7 8 9 "); - log_text(logtext); - sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", 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]); - log_text(logtext); - sprintf(logtext, "Distribution of store creator chains second part"); - log_text(logtext); - sprintf(logtext, " 10 11 12 13 14 15 16 17 18 19 >=20"); - log_text(logtext); - sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", 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]); - log_text(logtext); - sprintf(logtext, "Distribution of analysis iterations"); - log_text(logtext); - sprintf(logtext, " 1 2 3 4 >=5"); - log_text(logtext); - sprintf(logtext, "%5d%5d%5d%5d%5d", count_analyse_iterations[0], count_analyse_iterations[1], - count_analyse_iterations[2], count_analyse_iterations[3], count_analyse_iterations[4]); - log_text(logtext); - sprintf(logtext, "Distribution of basic blocks per method"); - log_text(logtext); - sprintf(logtext, " <= 5 <=10 <=15 <=20 <=30 <=40 <=50 <=75 >75"); - log_text(logtext); - sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_method_bb_distribution[0], - count_method_bb_distribution[1], count_method_bb_distribution[2], count_method_bb_distribution[3], - count_method_bb_distribution[4], count_method_bb_distribution[5], count_method_bb_distribution[6], - count_method_bb_distribution[7], count_method_bb_distribution[8]); - log_text(logtext); - sprintf(logtext, "Distribution of basic block sizes"); - log_text(logtext); - sprintf(logtext, - " 0 1 2 3 4 5 6 7 8 9 <13 <15 <17 <19 <21 <26 <31 >30"); - log_text(logtext); - sprintf(logtext, "%3d%5d%5d%5d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d", - count_block_size_distribution[0], count_block_size_distribution[1], count_block_size_distribution[2], - count_block_size_distribution[3], count_block_size_distribution[4], count_block_size_distribution[5], - count_block_size_distribution[6], count_block_size_distribution[7], count_block_size_distribution[8], - count_block_size_distribution[9], count_block_size_distribution[10], count_block_size_distribution[11], - count_block_size_distribution[12], count_block_size_distribution[13], count_block_size_distribution[14], - count_block_size_distribution[15], count_block_size_distribution[16], count_block_size_distribution[17]); - log_text(logtext); - sprintf(logtext, "Size of Code Area (Kb): %10.3f", (float) count_code_len / 1024); - log_text(logtext); - sprintf(logtext, "Size of data Area (Kb): %10.3f", (float) count_data_len / 1024); - log_text(logtext); - sprintf(logtext, "Size of Class Infos (Kb):%10.3f", (float) (count_class_infos) / 1024); - log_text(logtext); - sprintf(logtext, "Size of Const Pool (Kb): %10.3f", (float) (count_const_pool_len + count_utf_len) / 1024); - log_text(logtext); - sprintf(logtext, "Size of Vftbl (Kb): %10.3f", (float) count_vftbl_len / 1024); - log_text(logtext); - sprintf(logtext, "Size of comp stub (Kb): %10.3f", (float) count_cstub_len / 1024); - log_text(logtext); - sprintf(logtext, "Size of native stub (Kb):%10.3f", (float) count_nstub_len / 1024); - log_text(logtext); - sprintf(logtext, "Size of Utf (Kb): %10.3f", (float) count_utf_len / 1024); - log_text(logtext); - sprintf(logtext, "Size of VMCode (Kb): %10.3f(%d)", (float) count_vmcode_len / 1024, - count_vmcode_len - 18 * count_all_methods); - log_text(logtext); - sprintf(logtext, "Size of ExTable (Kb): %10.3f", (float) count_extable_len / 1024); - log_text(logtext); - sprintf(logtext, "Number of class loads: %d", count_class_loads); - log_text(logtext); - sprintf(logtext, "Number of class inits: %d", count_class_inits); - log_text(logtext); - sprintf(logtext, "Number of loaded Methods: %d\n\n", count_all_methods); - log_text(logtext); - - sprintf(logtext, "Calls of utf_new: %22d", count_utf_new); - log_text(logtext); - sprintf(logtext, "Calls of utf_new (element found): %6d\n\n", count_utf_new_found); - log_text(logtext); -} - - -/********** Function: class_compile_methods (debugging only) ********/ - -void class_compile_methods() -{ - int i; - classinfo *c; - methodinfo *m; - - c = list_first(&linkedclasses); - while (c) { - for (i = 0; i < c -> methodscount; i++) { - m = &(c->methods[i]); - if (m->jcode) { - (void) jit_compile(m); - } - } - c = list_next(&linkedclasses, c); - } -} +#ifdef TYPECHECK_STATISTICS +void typecheck_print_statistics(FILE *file); +#endif /* @@ -553,28 +243,30 @@ void exit_handler(void) { /********************* Print debug tables ************************/ - if (showmethods) class_showmethods(topclass); - if (showconstantpool) class_showconstantpool(topclass); + if (showmethods) class_showmethods(mainclass); + if (showconstantpool) class_showconstantpool(mainclass); if (showutf) utf_show(); -#ifdef USE_THREADS +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) clear_thread_flags(); /* restores standard file descriptor flags */ #endif /************************ Free all resources *******************/ - heap_close(); /* must be called before compiler_close and - loader_close because finalization occurs - here */ - loader_close(); - tables_close(literalstring_free); + tables_close(); - if (verbose || getcompilingtime || statistics) { + MFREE(classpath, u1, strlen(classpath)); + + if (opt_verbose || getcompilingtime || opt_stat) { log_text("CACAO terminated"); - if (statistics) + if (opt_stat) { print_stats(); +#ifdef TYPECHECK_STATISTICS + typecheck_print_statistics(get_logfile()); +#endif + } if (getcompilingtime) print_times(); mem_usagelog(1); @@ -591,31 +283,43 @@ void exit_handler(void) int main(int argc, char **argv) { s4 i, j; - char *cp; void *dummy; /********** interne (nur fuer main relevante Optionen) **************/ char logfilename[200] = ""; - u4 heapsize = 64000000; - u4 heapstartsize = 200000; - char classpath[500] = "."; + u4 heapmaxsize = 64 * 1024 * 1024; + u4 heapstartsize = 200 * 1024; + char *cp; + s4 cplen; bool startit = true; char *specificmethodname = NULL; char *specificsignature = NULL; -#ifndef USE_THREADS +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) stackbottom = &dummy; #endif - if (0 != atexit(exit_handler)) - panic("unable to register exit_handler"); + if (atexit(exit_handler)) + throw_cacao_exception_exit(string_java_lang_InternalError, + "Unable to register exit_handler"); + /************ Collect info from the environment ************************/ + /* set an initial, minimal classpath */ + classpath = MNEW(char, 2); + strcpy(classpath, "."); + + /* get classpath environment */ cp = getenv("CLASSPATH"); if (cp) { - strcpy(classpath, cp); + classpath = MREALLOC(classpath, + char, + strlen(classpath), + strlen(classpath) + 1 + strlen(cp) + 1); + strcat(classpath, ":"); + strcat(classpath, cp); } /***************** Interpret the command line *****************/ @@ -623,13 +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: - strcpy(classpath + strlen(classpath), ":"); - strcpy(classpath + strlen(classpath), opt_arg); + 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_D: @@ -639,42 +347,51 @@ 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: ; } break; - + case OPT_MS: case OPT_MX: - if (opt_arg[strlen(opt_arg) - 1] == 'k') { - j = 1024 * atoi(opt_arg); - } - else if (opt_arg[strlen(opt_arg) - 1] == 'm') { - j = 1024 * 1024 * atoi(opt_arg); + { + 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; } - else j = atoi(opt_arg); - - if (i == OPT_MX) heapsize = j; - else heapstartsize = j; break; case OPT_VERBOSE1: - verbose = true; + opt_verbose = true; break; - + case OPT_VERBOSE: - verbose = true; + opt_verbose = true; loadverbose = true; + linkverbose = true; initverbose = true; compileverbose = true; break; - + + case OPT_VERBOSEEXCEPTION: + verboseexception = true; + break; + case OPT_VERBOSEGC: collectverbose = true; break; @@ -697,6 +414,10 @@ int main(int argc, char **argv) opt_verify = false; break; + case OPT_LIBERALUTF: + opt_liberalutf = true; + break; + case OPT_SOFTNULL: checknull = true; break; @@ -707,7 +428,7 @@ int main(int argc, char **argv) break; case OPT_STAT: - statistics = true; + opt_stat = true; break; case OPT_LOG: @@ -724,8 +445,7 @@ int main(int argc, char **argv) checksync = false; break; default: - print_usage(); - exit(10); + usage(); } } break; @@ -735,18 +455,22 @@ int main(int argc, char **argv) makeinitializations = false; break; + case OPT_EAGER: + opt_eager = true; + break; + case OPT_METHOD: startit = false; - specificmethodname = opt_arg; + specificmethodname = opt_arg; makeinitializations = false; break; case OPT_SIGNATURE: - specificsignature = opt_arg; + specificsignature = opt_arg; break; case OPT_ALL: - compileall = true; + compileall = true; startit = false; makeinitializations = false; break; @@ -756,7 +480,7 @@ int main(int argc, char **argv) switch (opt_arg[j]) { case 'a': showdisassemble = true; - compileverbose=true; + compileverbose = true; break; case 'c': showconstantpool = true; @@ -775,8 +499,7 @@ int main(int argc, char **argv) showutf = true; break; default: - print_usage(); - exit(10); + usage(); } } break; @@ -789,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; @@ -804,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; @@ -821,92 +551,138 @@ 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--) { + if (mainstring[i] == '.') mainstring[i] = '/'; } /**************************** Program start *****************************/ log_init(logfilename); - if (verbose) { + if (opt_verbose) log_text("CACAO started -------------------------------------------------------"); - } - native_setclasspath(classpath); - + /* initialize the garbage collector */ + gc_init(heapmaxsize, heapstartsize); + tables_init(); suck_init(classpath); - heap_init(heapsize, heapstartsize, &dummy); - - jit_init(); + cacao_initializing = true; - loader_init((u1 *) &dummy); +#if defined(USE_THREADS) +#if defined(NATIVE_THREADS) + initThreadsEarly(); +#endif + initLocks(); +#endif - native_loadclasses(); + /* install architecture dependent signal handler used for exceptions */ + init_exceptions(); + /* initializes jit compiler and codegen stuff */ + jit_init(); - /*********************** Load JAVA classes ***************************/ - - cp = argv[opt_ind++]; - for (i = strlen(cp) - 1; i >= 0; i--) { /* Transform dots into slashes */ - if (cp[i] == '.') cp[i] = '/'; /* in the class name */ - } + loader_init((u1 *) &dummy); - /*printf("-------------------->%s\n",cp);*/ - topclass = loader_load(utf_new_char(cp)); - /*class_showmethods(topclass); */ + /* initialize exceptions used in the system */ + if (!init_system_exceptions()) + throw_main_exception_exit(); - if (exceptionptr != 0) { - printf("Exception in thread \"main\" "); - utf_display(exceptionptr->vftbl->class->name); - printf(": "); - utf_display(javastring_toutf(((java_lang_Throwable *) exceptionptr)->detailMessage, false)); - printf("\n"); + native_loadclasses(); - exceptionptr = 0; - } +#if defined(USE_THREADS) + initThreads((u1 *) &dummy); +#endif - if (topclass == 0) { - /* should we print out something? we already have the exception */ - exit(1); - } + *threadrootmethod = NULL; - /* initialize the garbage collector */ - gc_init(); + /*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!!! */ -#ifdef USE_THREADS - initThreads((u1*) &dummy); -#endif + if (!class_init(class_new(utf_new_char("java/lang/System")))) + throw_main_exception_exit(); + + +/* jni_init(); */ + cacao_initializing = false; /************************* Start worker routines ********************/ 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)); -/* heap_addreference((void**) &a); */ + if (!class_load(mainclass)) + throw_main_exception_exit(); - mainmethod = class_findmethod(topclass, - utf_new_char("main"), - utf_new_char("([Ljava/lang/String;)V") - ); + if (!class_link(mainclass)) + throw_main_exception_exit(); + + mainmethod = class_resolveclassmethod(mainclass, + utf_new_char("main"), + utf_new_char("([Ljava/lang/String;)V"), + mainclass, + false); + + /* problems with main method? */ +/* if (*exceptionptr) */ +/* throw_exception_exit(); */ /* there is no main method or it isn't static */ if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) { - printf("Exception in thread \"main\" java.lang.NoSuchMethodError: main\n"); - exit(1); + *exceptionptr = + new_exception_message(string_java_lang_NoSuchMethodError, + "main"); + throw_main_exception_exit(); } a = builtin_anewarray(argc - opt_ind, class_java_lang_String); @@ -921,31 +697,67 @@ int main(int argc, char **argv) #endif /*class_showmethods(currentThread->group->header.vftbl->class); */ + *threadrootmethod = mainmethod; + + /* here we go... */ asm_calljavafunction(mainmethod, a, NULL, NULL, NULL); - - if (exceptionptr) { - printf("Exception in thread \"main\" "); - utf_display(exceptionptr->vftbl->class->name); - - /* do we have a detail message? */ - if (((java_lang_Throwable *) exceptionptr)->detailMessage) { - printf(": "); - utf_display(javastring_toutf(((java_lang_Throwable *) exceptionptr)->detailMessage, false)); - } - printf("\n"); + + /* exception occurred? */ + if (*exceptionptr) { + throw_main_exception(); + status = 1; } -#ifdef USE_THREADS +#if defined(USE_THREADS) +#if defined(NATIVE_THREADS) + joinAllThreads(); +#else killThread(currentThread); #endif - fprintf(stderr, "still here\n"); +#endif + + /* now exit the JavaVM */ + + cacao_exit(status); } /************* If requested, compile all methods ********************/ if (compileall) { - class_compile_methods(); + classinfo *c; + methodinfo *m; + u4 slot; + s4 i; + + /* create all classes found in the classpath */ + /* XXX currently only works with zip/jar's */ + create_all_classes(); + + /* load and link all classes */ + for (slot = 0; slot < class_hash.size; slot++) { + c = class_hash.ptr[slot]; + + while (c) { + if (!c->loaded) + if (!class_load(c)) + throw_main_exception_exit(); + + if (!c->linked) + if (!class_link(c)) + throw_main_exception_exit(); + + /* compile all class methods */ + for (i = 0; i < c->methodscount; i++) { + m = &(c->methods[i]); + if (m->jcode) { + (void) jit_compile(m); + } + } + + c = c->hashlink; + } + } } @@ -953,46 +765,119 @@ int main(int argc, char **argv) if (specificmethodname) { methodinfo *m; + + /* create, load and link the main class */ + mainclass = class_new(utf_new_char(mainstring)); + + if (!class_load(mainclass)) + throw_main_exception_exit(); + + if (!class_link(mainclass)) + throw_main_exception_exit(); + if (specificsignature) { - m = class_findmethod(topclass, - utf_new_char(specificmethodname), - utf_new_char(specificsignature)); + m = class_resolveclassmethod(mainclass, + utf_new_char(specificmethodname), + utf_new_char(specificsignature), + mainclass, + false); } else { - m = class_findmethod(topclass, - utf_new_char(specificmethodname), - NULL); + m = class_resolveclassmethod(mainclass, + utf_new_char(specificmethodname), + NULL, + mainclass, + false); } - if (!m) - panic("Specific method not found"); + if (!m) { + char message[MAXLOGTEXT]; + sprintf(message, "%s%s", specificmethodname, + specificsignature ? specificsignature : ""); + + *exceptionptr = + new_exception_message(string_java_lang_NoSuchMethodException, + message); + + throw_main_exception_exit(); + } jit_compile(m); } - exit(0); + cacao_shutdown(0); + + /* keep compiler happy */ + + return 0; } +/* cacao_exit ****************************************************************** -/************************************ Shutdown function ********************************* + Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly. + +*******************************************************************************/ + +void cacao_exit(s4 status) +{ + classinfo *c; + methodinfo *m; + + /* class should already be loaded, but who knows... */ + + c = class_new(utf_new_char("java/lang/System")); + + if (!class_load(c)) + throw_main_exception_exit(); + + if (!class_link(c)) + throw_main_exception_exit(); + + /* call System.exit(I)V */ + + m = class_resolveclassmethod(c, + utf_new_char("exit"), + utf_new_char("(I)V"), + class_java_lang_Object, + true); + + if (!m) + throw_main_exception_exit(); + + /* 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, + "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) { - /**** RTAprint ***/ - - if (verbose || getcompilingtime || statistics) { - log_text ("CACAO terminated by shutdown"); - if (statistics) - print_stats(); - if (getcompilingtime) - print_times(); - mem_usagelog(0); - dolog("Exit status: %d\n", (int) status); + if (opt_verbose || getcompilingtime || opt_stat) { + log_text("CACAO terminated by shutdown"); + dolog("Exit status: %d\n", (s4) status); } exit(status);