X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fcacao%2Fcacao.c;h=1734b12b719c824f39256aeb3138d4c28fed52a7;hb=f6f8c0940a0270d1c79901f071fd90ce50e34ae6;hp=aee43a89d7b7ca571c51e4a48cdac6b4eacdf512;hpb=1de18565f935e94fd4b9a61bc3102a39912023ce;p=cacao.git diff --git a/src/cacao/cacao.c b/src/cacao/cacao.c index aee43a89d..1734b12b7 100644 --- a/src/cacao/cacao.c +++ b/src/cacao/cacao.c @@ -1,66 +1,79 @@ -/* main.c ********************************************************************** +/* cacao/cacao.c - contains main() of cacao - Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst + 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 - See file COPYRIGHT for information on usage and disclaimer of warranties + This file is part of CACAO. - Enthaelt die Funktion main() und die Variablen fuer die - globalen Optionen. - Dieser Modul erledigt folgende Aufgaben: - - Bearbeiten der command-line-options - - Aufrufen aller Initialisierungsroutinen - - Aufrufen des Classloaders - - Starten der main - Methode + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. - Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at - Changes: Andi Krall EMAIL: cacao@complang.tuwien.ac.at - Mark Probst EMAIL: cacao@complang.tuwien.ac.at + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - Last Change: 1997/10/29 + 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. -*******************************************************************************/ + Contact: cacao@complang.tuwien.ac.at -#include "global.h" + Authors: Reinhard Grafl -#include "tables.h" -#include "loader.h" -#include "jit.h" -#ifdef OLD_COMPILER -#include "compiler.h" -#endif + Changes: Andi Krall + Mark Probst + Philipp Tomsich -#include "asmpart.h" -#include "builtin.h" -#include "native.h" + This module does the following tasks: + - Command line option handling + - Calling initialization routines + - Calling the class loader + - Running the main method -#include "threads/thread.h" + $Id: cacao.c 1801 2004-12-21 20:19:19Z jowenn $ -bool compileall = false; -int newcompiler = true; -bool verbose = false; -#ifdef NEW_GC -bool new_gc = false; -#endif +*/ -static bool showmethods = false; -static bool showconstantpool = false; -static bool showunicode = false; -static classinfo *topclass; -#ifndef USE_THREADS -void **stackbottom = 0; +#include +#include + +#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" + +#ifdef TYPEINFO_DEBUG_TEST +#include "vm/jit/verify/typeinfo.h" #endif -/* internal function: get_opt ************************************************* - - decodes the next command line option - -******************************************************************************/ +bool cacao_initializing; + +char *classpath; /* contains classpath */ +char *mainstring; +static classinfo *mainclass; -#define OPT_DONE -1 -#define OPT_ERROR 0 -#define OPT_IGNORE 1 +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) +void **stackbottom = 0; +#endif + +/* define command line options ************************************************/ #define OPT_CLASSPATH 2 #define OPT_D 3 @@ -70,7 +83,7 @@ void **stackbottom = 0; #define OPT_VERBOSE 7 #define OPT_VERBOSEGC 8 #define OPT_VERBOSECALL 9 -#define OPT_IEEE 10 +#define OPT_NOIEEE 10 #define OPT_SOFTNULL 11 #define OPT_TIME 12 #define OPT_STAT 13 @@ -81,364 +94,144 @@ void **stackbottom = 0; #define OPT_SIGNATURE 18 #define OPT_SHOW 19 #define OPT_ALL 20 -#ifdef OLD_COMPILER -#define OPT_OLD 21 +#define OPT_OLOOP 24 +#define OPT_INLINING 25 +#ifdef STATIC_ANALYSIS +#define OPT_RT 26 +#define OPT_XTA 27 +#define OPT_VTA 28 #endif -#ifdef NEW_GC -#define OPT_GC1 22 -#define OPT_GC2 23 +#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_IGNORE}, - {"oss", true, OPT_IGNORE}, - {"ss", true, OPT_IGNORE}, - {"v", false, OPT_VERBOSE1}, - {"verbose", false, OPT_VERBOSE}, - {"verbosegc", false, OPT_VERBOSEGC}, - {"verbosecall", false, OPT_VERBOSECALL}, - {"ieee", false, OPT_IEEE}, - {"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}, -#ifdef OLD_COMPILER - {"old", false, OPT_OLD}, +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}, + {"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 NEW_GC - {"gc1", false, OPT_GC1}, - {"gc2", false, OPT_GC2}, +#ifdef LSRA + {"lsra", false, OPT_LSRA}, #endif - {NULL, false, 0} + {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 Funktion: print_usage ************************ +/******************** interne Function: print_usage ************************ -Gibt die richtige Aufrufsyntax des JavaVM-Compilers auf stdout aus. +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 (" -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 (" -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 (" -ieee ................ use ieee compliant arithmetic\n"); - printf (" -softnull ............ use software nullpointer check\n"); - printf (" -time ................ measure the runtime\n"); - printf (" -stat ................ detailed compiler statistics\n"); - 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 (" -l ................... don't start the class after loading\n"); - printf (" -all ................. compile all methods, no execution\n"); -#ifdef OLD_COMPILER - printf (" -old ................. use old JIT compiler\n"); + 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(" -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 -#ifdef NEW_GC - printf (" -gc1 ................. use the old garbage collector (default)\n"); - printf (" -gc2 ................. use the new garbage collector\n"); +#if defined(__ALPHA__) + printf(" -noieee .............. don't use ieee compliant arithmetic\n"); #endif - 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"); -#ifdef OLD_COMPILER - printf (" s(tack) ....... show stack for every javaVM-command\n"); + 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"); + 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 - printf (" u(nicode) ..... show the unicode - hash\n"); -} - - - -/***************************** Funktion: print_times ********************* - - gibt eine Aufstellung der verwendeten CPU-Zeit aus - -**************************************************************************/ - -static void print_times() -{ - long int totaltime = getcputime(); - long int runtime = totaltime - loadingtime - compilingtime; - - sprintf (logtext, "Time for loading classes: %ld secs, %ld millis", - loadingtime / 1000000, (loadingtime % 1000000) / 1000); - dolog(); - sprintf (logtext, "Time for compiling code: %ld secs, %ld millis", - compilingtime / 1000000, (compilingtime % 1000000) / 1000); - dolog(); - sprintf (logtext, "Time for running program: %ld secs, %ld millis", - runtime / 1000000, (runtime % 1000000) / 1000); - dolog(); - sprintf (logtext, "Total time: %ld secs, %ld millis", - totaltime / 1000000, (totaltime % 1000000) / 1000); - dolog(); -} - - - - - - -/***************************** Funktion: print_stats ********************* - - outputs detailed compiler statistics - -**************************************************************************/ -static void print_stats() -{ - sprintf (logtext, "Number of JitCompiler Calls: %d", count_jit_calls); - dolog(); - sprintf (logtext, "Number of compiled Methods: %d", count_methods); - dolog(); - sprintf (logtext, "Number of max basic blocks per method: %d", count_max_basic_blocks); - dolog(); - sprintf (logtext, "Number of compiled basic blocks: %d", count_basic_blocks); - dolog(); - sprintf (logtext, "Number of max JavaVM-Instructions per method: %d", count_max_javainstr); - dolog(); - sprintf (logtext, "Number of compiled JavaVM-Instructions: %d", count_javainstr); - dolog(); - sprintf (logtext, "Size of compiled JavaVM-Instructions: %d(%d)", count_javacodesize, - count_javacodesize - count_methods * 18); - dolog(); - sprintf (logtext, "Size of compiled Exception Tables: %d", count_javaexcsize); - dolog(); - sprintf (logtext, "Value of extended instruction set var: %d", has_ext_instr_set); - dolog(); - sprintf (logtext, "Number of Alpha-Instructions: %d", count_code_len >> 2); - dolog(); - sprintf (logtext, "Number of Spills: %d", count_spills); - dolog(); - sprintf (logtext, "Number of Activ Pseudocommands: %5d", count_pcmd_activ); - dolog(); - sprintf (logtext, "Number of Drop Pseudocommands: %5d", count_pcmd_drop); - dolog(); - sprintf (logtext, "Number of Const Pseudocommands: %5d (zero:%5d)", count_pcmd_load, count_pcmd_zero); - dolog(); - sprintf (logtext, "Number of ConstAlu Pseudocommands: %5d (cmp: %5d, store:%5d)", count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store); - dolog(); - sprintf (logtext, "Number of Move Pseudocommands: %5d", count_pcmd_move); - dolog(); - sprintf (logtext, "Number of Load Pseudocommands: %5d", count_load_instruction); - dolog(); - sprintf (logtext, "Number of Store Pseudocommands: %5d (combined: %5d)", count_pcmd_store, count_pcmd_store - count_pcmd_store_comb); - dolog(); - sprintf (logtext, "Number of OP Pseudocommands: %5d", count_pcmd_op); - dolog(); - sprintf (logtext, "Number of DUP Pseudocommands: %5d", count_dup_instruction); - dolog(); - sprintf (logtext, "Number of Mem Pseudocommands: %5d", count_pcmd_mem); - dolog(); - sprintf (logtext, "Number of Method Pseudocommands: %5d", count_pcmd_met); - dolog(); - sprintf (logtext, "Number of Branch Pseudocommands: %5d (rets:%5d, Xrets: %5d)", - count_pcmd_bra, count_pcmd_return, count_pcmd_returnx); - dolog(); - sprintf (logtext, "Number of Table Pseudocommands: %5d", count_pcmd_table); - dolog(); - sprintf (logtext, "Number of Useful Pseudocommands: %5d", count_pcmd_table + - count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op); - dolog(); - sprintf (logtext, "Number of Null Pointer Checks: %5d", count_check_null); - dolog(); - sprintf (logtext, "Number of Array Bound Checks: %5d", count_check_bound); - dolog(); - sprintf (logtext, "Number of Try-Blocks: %d", count_tryblocks); - dolog(); - sprintf (logtext, "Maximal count of stack elements: %d", count_max_new_stack); - dolog(); - sprintf (logtext, "Upper bound of max stack elements: %d", count_upper_bound_new_stack); - dolog(); - sprintf (logtext, "Distribution of stack sizes at block boundary"); - dolog(); - sprintf (logtext, " 0 1 2 3 4 5 6 7 8 9 >=10"); - dolog(); - 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]); - dolog(); - sprintf (logtext, "Distribution of store stack depth"); - dolog(); - sprintf (logtext, " 0 1 2 3 4 5 6 7 8 9 >=10"); - dolog(); - 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]); - dolog(); - sprintf (logtext, "Distribution of store creator chains first part"); - dolog(); - sprintf (logtext, " 0 1 2 3 4 5 6 7 8 9 "); - dolog(); - 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]); - dolog(); - sprintf (logtext, "Distribution of store creator chains second part"); - dolog(); - sprintf (logtext, " 10 11 12 13 14 15 16 17 18 19 >=20"); - dolog(); - 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]); - dolog(); - sprintf (logtext, "Distribution of analysis iterations"); - dolog(); - sprintf (logtext, " 1 2 3 4 >=5"); - dolog(); - 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]); - dolog(); - sprintf (logtext, "Distribution of basic blocks per method"); - dolog(); - sprintf (logtext, " <= 5 <=10 <=15 <=20 <=30 <=40 <=50 <=75 >75"); - dolog(); - 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]); - dolog(); - sprintf (logtext, "Distribution of basic block sizes"); - dolog(); - sprintf (logtext, - " 1 2 3 4 5 6 7 8 9 10 <13 <15 <17 <19 <21 <26 <31 >30"); - dolog(); - 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]); - dolog(); - sprintf (logtext, "Size of Code Area (Kb): %10.3f", (float) count_code_len / 1024); - dolog(); - sprintf (logtext, "Size of data Area (Kb): %10.3f", (float) count_data_len / 1024); - dolog(); - sprintf (logtext, "Size of Class Infos (Kb):%10.3f", (float) (count_class_infos) / 1024); - dolog(); - sprintf (logtext, "Size of Const Pool (Kb): %10.3f", (float) (count_const_pool_len + count_unicode_len) / 1024); - dolog(); - sprintf (logtext, "Size of Vftbl (Kb): %10.3f", (float) count_vftbl_len / 1024); - dolog(); - sprintf (logtext, "Size of comp stub (Kb): %10.3f", (float) count_cstub_len / 1024); - dolog(); - sprintf (logtext, "Size of native stub (Kb):%10.3f", (float) count_nstub_len / 1024); - dolog(); - sprintf (logtext, "Size of Unicode (Kb): %10.3f", (float) count_unicode_len / 1024); - dolog(); - sprintf (logtext, "Size of VMCode (Kb): %10.3f(%d)", (float) count_vmcode_len / 1024, - count_vmcode_len - 18 * count_all_methods); - dolog(); - sprintf (logtext, "Size of ExTable (Kb): %10.3f", (float) count_extable_len / 1024); - dolog(); - sprintf (logtext, "Number of loaded Methods: %d\n\n", count_all_methods); - dolog(); -} + /* exit with error code */ + exit(1); +} -/********** Funktion: class_compile_methods (nur f"ur Debug-Zwecke) ********/ -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) { -#ifdef OLD_COMPILER - if (newcompiler) -#endif - (void) jit_compile(m); -#ifdef OLD_COMPILER - else - (void) compiler_compile(m); +#ifdef TYPECHECK_STATISTICS +void typecheck_print_statistics(FILE *file); #endif - } - } - c = list_next (&linkedclasses, c); - } -} + /* * void exit_handler(void) @@ -446,147 +239,183 @@ void class_compile_methods () * 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) { - /********************* Debug-Tabellen ausgeben ************************/ + /********************* Print debug tables ************************/ - if (showmethods) class_showmethods (topclass); - if (showconstantpool) class_showconstantpool (topclass); - if (showunicode) unicode_show (); + 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 */ + flags */ #endif - /************************ Freigeben aller Resourcen *******************/ + /************************ Free all resources *******************/ - heap_close (); /* must be called before compiler_close and - loader_close because finalization occurs - here */ + loader_close(); + tables_close(); -#ifdef OLD_COMPILER - compiler_close (); -#endif - loader_close (); - unicode_close ( literalstring_free ); + MFREE(classpath, u1, strlen(classpath)); - if (verbose || getcompilingtime || statistics) { - log_text ("CACAO terminated"); - if (statistics) - print_stats (); + if (opt_verbose || getcompilingtime || opt_stat) { + log_text("CACAO terminated"); + if (opt_stat) { + print_stats(); +#ifdef TYPECHECK_STATISTICS + typecheck_print_statistics(get_logfile()); +#endif + } if (getcompilingtime) - print_times (); + print_times(); mem_usagelog(1); } } -/************************** Funktion: main ******************************* - Das Hauptprogramm. - Wird vom System zu Programstart aufgerufen (eh klar). +/************************** Function: main ******************************* + + The main program. **************************************************************************/ int main(int argc, char **argv) { - s4 i,j; - char *cp; - java_objectheader *exceptionptr; + s4 i, j; void *dummy; /********** interne (nur fuer main relevante Optionen) **************/ char logfilename[200] = ""; - u4 heapsize = 16000000; - u4 heapstartsize = 200000; - char classpath[500] = ".:/usr/local/lib/java/classes"; + 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 ************************/ - /************ Infos aus der Environment lesen ************************/ + /* set an initial, minimal classpath */ + classpath = MNEW(char, 2); + strcpy(classpath, "."); - cp = getenv ("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); } - /***************** Interpretieren der Kommandozeile *****************/ + /***************** Interpret the command line *****************/ checknull = false; - checkfloats = false; - - while ( (i = get_opt(argc,argv)) != OPT_DONE) { + opt_noieee = false; + 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: { - int n,l=strlen(opt_arg); - for (n=0; n= argc) { - print_usage (); - exit(10); } + if (opt_ind >= argc) + usage(); + - /**************************** Programmstart *****************************/ + /* insert the rt.jar in front of all other classpath entries */ - log_init (logfilename); - if (verbose) { - log_text ( - "CACAO started -------------------------------------------------------"); + 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] = '/'; } - - suck_init (classpath); - native_setclasspath (classpath); - - unicode_init(); - heap_init(heapsize, heapstartsize, &dummy); - loader_init(); -#ifdef OLD_COMPILER - compiler_init(); + + + /**************************** Program start *****************************/ + + log_init(logfilename); + if (opt_verbose) + log_text("CACAO started -------------------------------------------------------"); + + /* initialize the garbage collector */ + gc_init(heapmaxsize, heapstartsize); + + tables_init(); + suck_init(classpath); + + cacao_initializing = true; + +#if defined(USE_THREADS) +#if defined(NATIVE_THREADS) + initThreadsEarly(); +#endif + initLocks(); #endif + + /* install architecture dependent signal handler used for exceptions */ + init_exceptions(); + + /* initializes jit compiler and codegen stuff */ jit_init(); - native_loadclasses (); + loader_init((u1 *) &dummy); + /* initialize exceptions used in the system */ + if (!init_system_exceptions()) + throw_main_exception_exit(); - /*********************** JAVA-Klassen laden ***************************/ - - cp = argv[opt_ind++]; - for (i=strlen(cp)-1; i>=0; i--) { /* Punkte im Klassennamen */ - if (cp[i]=='.') cp[i]='/'; /* auf slashes umbauen */ - } + native_loadclasses(); - topclass = loader_load ( unicode_new_char (cp) ); +#if defined(USE_THREADS) + initThreads((u1 *) &dummy); +#endif - loader_compute_subclasses(); + *threadrootmethod = NULL; - 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); /* schani */ -#endif + if (!class_init(class_new(utf_new_char("java/lang/System")))) + throw_main_exception_exit(); - /************************* Arbeitsroutinen starten ********************/ + + +/* jni_init(); */ + cacao_initializing = false; + + /************************* Start worker routines ********************/ if (startit) { methodinfo *mainmethod; java_objectarray *a; + s4 status; - heap_addreference((void**) &a); + /* set return value to OK */ + status = 0; - mainmethod = class_findmethod ( - topclass, - unicode_new_char ("main"), - unicode_new_char ("([Ljava/lang/String;)V") - ); - if (!mainmethod) panic ("Can not find method 'void main(String[])'"); - if ((mainmethod->flags & ACC_STATIC) != ACC_STATIC) panic ("main is not static!"); - - a = builtin_anewarray (argc - opt_ind, class_java_lang_String); - for (i=opt_ind; idata[i-opt_ind] = javastring_new (unicode_new_char (argv[i]) ); + /* 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(); + + 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)) { + *exceptionptr = + new_exception_message(string_java_lang_NoSuchMethodError, + "main"); + throw_main_exception_exit(); } - exceptionptr = asm_calljavamethod (mainmethod, a, NULL,NULL,NULL ); - - if (exceptionptr) { - printf ("#### Program has thrown: "); - unicode_display (exceptionptr->vftbl->class->name); - printf ("\n"); + + 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])); } - killThread(currentThread); - fprintf(stderr, "still here\n"); +#ifdef TYPEINFO_DEBUG_TEST + /* test the typeinfo system */ + typeinfo_test(); +#endif + /*class_showmethods(currentThread->group->header.vftbl->class); */ + + *threadrootmethod = mainmethod; + + + /* here we go... */ + asm_calljavafunction(mainmethod, a, NULL, NULL, NULL); + + /* exception occurred? */ + if (*exceptionptr) { + throw_main_exception(); + status = 1; + } + +#if defined(USE_THREADS) +#if defined(NATIVE_THREADS) + joinAllThreads(); +#else + killThread(currentThread); +#endif +#endif + + /* now exit the JavaVM */ + + cacao_exit(status); } - /************* Auf Wunsch alle Methode "ubersetzen ********************/ + /************* 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; + } + } } - /******** Auf Wunsch eine spezielle Methode "ubersetzen ***************/ + /******** If requested, compile a specific method ***************/ if (specificmethodname) { methodinfo *m; - if (specificsignature) - m = class_findmethod(topclass, - unicode_new_char(specificmethodname), - unicode_new_char(specificsignature)); - else - m = class_findmethod(topclass, - unicode_new_char(specificmethodname), NULL); - if (!m) panic ("Specific method not found"); -#ifdef OLD_COMPILER - if (newcompiler) -#endif - (void) jit_compile(m); -#ifdef OLD_COMPILER - else - (void) compiler_compile(m); -#endif + + /* 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_resolveclassmethod(mainclass, + utf_new_char(specificmethodname), + utf_new_char(specificsignature), + mainclass, + false); + } else { + m = class_resolveclassmethod(mainclass, + utf_new_char(specificmethodname), + NULL, + mainclass, + false); + } + + 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-Funktion ********************************* + Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly. - Terminiert das System augenblicklich, ohne den Speicher - explizit freizugeben (eigentlich nur f"ur abnorme - Programmterminierung) +*******************************************************************************/ + +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 */ + + /* both inlinevirtual and outsiders not allowed on exit */ + /* not sure if permanant or temp restriction */ + if (inlinevirtuals) inlineoutsiders = false; + + 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) { - if (verbose || getcompilingtime || statistics) { - log_text ("CACAO terminated by shutdown"); - if (statistics) - print_stats (); - if (getcompilingtime) - print_times (); - mem_usagelog(0); - sprintf (logtext, "Exit status: %d\n", (int) status); - dolog(); - } + if (opt_verbose || getcompilingtime || opt_stat) { + log_text("CACAO terminated by shutdown"); + dolog("Exit status: %d\n", (s4) status); + } exit(status); }