X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fcacao%2Fcacao.c;h=1734b12b719c824f39256aeb3138d4c28fed52a7;hb=f6f8c0940a0270d1c79901f071fd90ce50e34ae6;hp=067fe7a9c299d742315dbccdb8b16341c6789874;hpb=22d2ecfa1401086f1371ed0667296ada50973d5c;p=cacao.git diff --git a/src/cacao/cacao.c b/src/cacao/cacao.c index 067fe7a9c..1734b12b7 100644 --- a/src/cacao/cacao.c +++ b/src/cacao/cacao.c @@ -1,761 +1,902 @@ -/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */ -/******************************* 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 "compiler.h" -#include "ncomp/ncomp.h" -#include "loader.h" + 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" /* schani */ + $Id: cacao.c 1801 2004-12-21 20:19:19Z jowenn $ -bool compileall = false; -int newcompiler = true; -bool verbose = false; +*/ -#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 -/********************* interne Funktion: get_opt ***************************** - - liest die n"achste Option aus der Kommandozeile - -******************************************************************************/ +bool cacao_initializing; + +char *classpath; /* contains classpath */ +char *mainstring; +static classinfo *mainclass; + +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) +void **stackbottom = 0; +#endif -#define OPT_DONE -1 -#define OPT_ERROR 0 -#define OPT_IGNORE 1 +/* define command line options ************************************************/ #define OPT_CLASSPATH 2 -#define OPT_D 3 -#define OPT_MS 4 -#define OPT_MX 5 -#define OPT_VERBOSE1 6 -#define OPT_VERBOSE 7 -#define OPT_VERBOSEGC 8 -#define OPT_VERBOSECALL 9 -#define OPT_IEEE 10 +#define OPT_D 3 +#define OPT_MS 4 +#define OPT_MX 5 +#define OPT_VERBOSE1 6 +#define OPT_VERBOSE 7 +#define OPT_VERBOSEGC 8 +#define OPT_VERBOSECALL 9 +#define OPT_NOIEEE 10 #define OPT_SOFTNULL 11 #define OPT_TIME 12 #define OPT_STAT 13 -#define OPT_LOG 14 +#define OPT_LOG 14 #define OPT_CHECK 15 -#define OPT_LOAD 16 -#define OPT_METHOD 17 -#define OPT_SIGNATURE 18 -#define OPT_SHOW 19 -#define OPT_ALL 20 -#define OPT_OLD 21 - -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 }, - { "old", false, OPT_OLD }, - { 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; -} - +#define OPT_LOAD 16 +#define OPT_METHOD 17 +#define OPT_SIGNATURE 18 +#define OPT_SHOW 19 +#define OPT_ALL 20 +#define OPT_OLOOP 24 +#define OPT_INLINING 25 +#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 +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 LSRA + {"lsra", false, OPT_LSRA}, +#endif + {NULL, false, 0} +}; -/******************** 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"); - printf (" -old ................. use old JIT compiler\n"); - printf (" -m ................... compile only a specific method\n"); - printf (" -sig ................. specify signature for a specific method\n"); - printf (" -s(how)m(ethods) ..... show all methods&fields of a class\n"); - printf (" c(onstants) ... show the constant pool\n"); - printf (" a(ssembler) ... show disassembled listing\n"); - printf (" d(atasegment).. show data segment listing\n"); - printf (" s(tack) ....... show stack for every javaVM-command\n"); - printf (" i(ntermediate). show intermediate representation\n"); - printf (" u(nicode) ..... show the unicode - hash\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 +#if defined(__ALPHA__) + printf(" -noieee .............. don't use ieee compliant arithmetic\n"); +#endif + printf(" -noverify ............ don't verify classfiles\n"); + printf(" -liberalutf........... don't warn about overlong UTF-8 sequences\n"); + printf(" -softnull ............ use software nullpointer check\n"); + printf(" -time ................ measure the runtime\n"); + 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 + /* exit with error code */ + exit(1); +} -/***************************** Funktion: print_times ********************* - gibt eine Aufstellung der verwendeten CPU-Zeit aus +#ifdef TYPECHECK_STATISTICS +void typecheck_print_statistics(FILE *file); +#endif -**************************************************************************/ -static void print_times() +/* + * void exit_handler(void) + * ----------------------- + * The exit_handler function is called upon program termination to shutdown + * the various subsystems and release the resources allocated to the VM. + */ +void exit_handler(void) { - 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 + /********************* Print debug tables ************************/ + + if (showmethods) class_showmethods(mainclass); + if (showconstantpool) class_showconstantpool(mainclass); + if (showutf) utf_show(); -**************************************************************************/ +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) + clear_thread_flags(); /* restores standard file descriptor + flags */ +#endif -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(); -} + /************************ Free all resources *******************/ + loader_close(); + tables_close(); -/********** Funktion: class_compile_methods (nur f"ur Debug-Zwecke) ********/ + MFREE(classpath, u1, strlen(classpath)); -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) { - if (newcompiler) - (void) new_compile(m); - else - (void) compiler_compile(m); - } - } - c = list_next (&linkedclasses, c); + 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(); + mem_usagelog(1); + } } -/************************** Funktion: main ******************************* +/************************** Function: main ******************************* - Das Hauptprogramm. - Wird vom System zu Programstart aufgerufen (eh klar). + The main program. **************************************************************************/ - int main(int argc, char **argv) { - s4 i,j; - char *cp; - classinfo *topclass; - java_objectheader *exceptionptr; + s4 i, j; void *dummy; - /********** interne (nur fuer main relevante Optionen) **************/ + /********** interne (nur fuer main relevante Optionen) **************/ char logfilename[200] = ""; - u4 heapsize = 16000000; - u4 heapstartsize = 200000; - char classpath[500] = ".:/usr/local/lib/java/classes"; - bool showmethods = false; - bool showconstantpool = false; - bool showunicode = false; + 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 (atexit(exit_handler)) + throw_cacao_exception_exit(string_java_lang_InternalError, + "Unable to register exit_handler"); -#ifdef USE_THREADS - atexit(clear_thread_flags); -#endif + /************ 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); - } - - /***************** Interpretieren der Kommandozeile *****************/ + classpath = MREALLOC(classpath, + char, + strlen(classpath), + strlen(classpath) + 1 + strlen(cp) + 1); + strcat(classpath, ":"); + strcat(classpath, cp); + } + + /***************** Interpret the command line *****************/ - checknull = false; - checkfloats = false; - - while ( (i = get_opt(argc,argv)) != OPT_DONE) { + checknull = false; + 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); - break; + case OPT_CLASSPATH: + /* forget old classpath and set the argument as new classpath */ + MFREE(classpath, char, strlen(classpath)); + + classpath = MNEW(char, strlen(opt_arg) + 1); + strcpy(classpath, opt_arg); + break; - case OPT_D: - { - int n,l=strlen(opt_arg); - for (n=0; n= argc) { - print_usage (); - exit(10); - } + case OPT_OLOOP: + opt_loops = true; + break; + + case OPT_INLINING: + for (j = 0; j < strlen(opt_arg); j++) { + switch (opt_arg[j]) { + case 'n': + /* define in options.h; Used in main.c, jit.c & inline.c */ + #ifdef INAFTERMAIN + useinliningm = true; + useinlining = false; + #else + useinlining = true; + #endif + break; + case 'v': + inlinevirtuals = true; + opt_rt = true; + break; + case 'e': + inlineexceptions = true; + break; + case 'p': + inlineparamopt = true; + break; + case 'o': + inlineoutsiders = true; + break; + default: + usage(); + } + } + break; + +#ifdef STATIC_ANALYSIS + case OPT_RT: + opt_rt = true; + break; + + case OPT_XTA: + opt_xta = false; /**not yet **/ + break; + case OPT_VTA: + /***opt_vta = true; not yet **/ + break; +#endif - /**************************** Programmstart *****************************/ +#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 - log_init (logfilename); - if (verbose) { - log_text ( - "CACAO started -------------------------------------------------------"); + default: + usage(); } - - suck_init (classpath); - native_setclasspath (classpath); - - unicode_init(); - heap_init(heapsize, heapstartsize, &dummy); - loader_init(); - compiler_init(); - ncomp_init(); + } - native_loadclasses (); + if (opt_ind >= argc) + usage(); - /*********************** 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 */ - } + /* 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 (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 - topclass = loader_load ( unicode_new_char (cp) ); + /* install architecture dependent signal handler used for exceptions */ + init_exceptions(); - loader_compute_subclasses(); + /* initializes jit compiler and codegen stuff */ + jit_init(); - gc_init(); + loader_init((u1 *) &dummy); -#ifdef USE_THREADS - initThreads((u1*)&dummy); /* schani */ + /* initialize exceptions used in the system */ + if (!init_system_exceptions()) + throw_main_exception_exit(); + + native_loadclasses(); + +#if defined(USE_THREADS) + initThreads((u1 *) &dummy); #endif - /************************* Arbeitsroutinen starten ********************/ + *threadrootmethod = NULL; + + /*That's important, otherwise we get into trouble, if the Runtime static + initializer is called before (circular dependency. This is with + classpath 0.09. Another important thing is, that this has to happen + after initThreads!!! */ + + 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; - 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]) ); - } - exceptionptr = asm_calljavamethod (mainmethod, a, NULL,NULL,NULL ); - - if (exceptionptr) { - printf ("#### Program has thrown: "); - unicode_display (exceptionptr->vftbl->class->name); - printf ("\n"); - } + /* create, load and link the main class */ + mainclass = class_new(utf_new_char(mainstring)); -/* killThread(currentThread); */ + 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(); } - /************* Auf Wunsch alle Methode "ubersetzen ********************/ + 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])); + } - if (compileall) { - class_compile_methods(); +#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 */ - /******** Auf Wunsch eine spezielle Methode "ubersetzen ***************/ + cacao_exit(status); + } - if (specificmethodname) { + /************* If requested, compile all methods ********************/ + + if (compileall) { + classinfo *c; 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"); - if (newcompiler) - (void) new_compile(m); - else - (void) compiler_compile(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); + } + } - /********************* Debug-Tabellen ausgeben ************************/ - - if (showmethods) class_showmethods (topclass); - if (showconstantpool) class_showconstantpool (topclass); - if (showunicode) unicode_show (); + c = c->hashlink; + } + } + } - - /************************ Freigeben aller Resourcen *******************/ + /******** If requested, compile a specific method ***************/ - heap_close (); /* must be called before compiler_close and - loader_close because finalization occurs - here */ - compiler_close (); - loader_close (); - unicode_close ( literalstring_free ); + 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_resolveclassmethod(mainclass, + utf_new_char(specificmethodname), + utf_new_char(specificsignature), + mainclass, + false); + } else { + m = class_resolveclassmethod(mainclass, + utf_new_char(specificmethodname), + NULL, + mainclass, + false); + } - /* Endemeldung ausgeben und mit entsprechendem exit-Status terminieren */ + if (!m) { + char message[MAXLOGTEXT]; + sprintf(message, "%s%s", specificmethodname, + specificsignature ? specificsignature : ""); - if (verbose || getcompilingtime || statistics) { - log_text ("CACAO terminated"); - if (statistics) - print_stats (); - if (getcompilingtime) - print_times (); - mem_usagelog(1); + *exceptionptr = + new_exception_message(string_java_lang_NoSuchMethodException, + message); + + throw_main_exception_exit(); } - exit(0); - return 1; + jit_compile(m); + } + + cacao_shutdown(0); + + /* keep compiler happy */ + + return 0; } +/* cacao_exit ****************************************************************** + + 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 */ + + /* 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-Funktion ********************************* +/*************************** Shutdown function ********************************* - Terminiert das System augenblicklich, ohne den Speicher - explizit freizugeben (eigentlich nur f"ur abnorme - Programmterminierung) + 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); } + + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + */