-/* main.c - contains main() and variables for the global options
+/* src/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.
Changes: Andi Krall
Mark Probst
Philipp Tomsich
+ Christian Thalinger
This module does the following tasks:
- Command line option handling
- Calling the class loader
- Running the main method
- $Id: cacao.c 991 2004-03-29 11:22:34Z stefan $
+ $Id: cacao.c 3570 2005-11-04 16:58:36Z motse $
*/
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
-#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 "nat/java_lang_Throwable.h"
-#ifdef TYPEINFO_DEBUG_TEST
-#include "typeinfo.h"
+#include "config.h"
+#include "cacao/cacao.h"
+#include "mm/boehm.h"
+#include "mm/memory.h"
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JVMTI)
+#include "native/jvmti/jvmti.h"
+#include "native/jvmti/dbg.h"
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/wait.h>
#endif
-/* command line option */
-
-bool verbose = false;
-bool compileall = false;
-bool runverbose = false; /* trace all method invocation */
-bool verboseexception = false; /* trace all method invocation */
-bool collectverbose = false;
+#include "toolbox/logging.h"
+#include "vm/exceptions.h"
+#include "vm/finalizer.h"
+#include "vm/global.h"
+#include "vm/initialize.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/signallocal.h"
+#include "vm/statistics.h"
+#include "vm/stringlocal.h"
+#include "vm/tables.h"
+#include "vm/classcache.h"
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
-bool loadverbose = false;
-bool linkverbose = false;
-bool initverbose = false;
+#ifdef TYPEINFO_DEBUG_TEST
+#include "vm/jit/verify/typeinfo.h"
+#endif
-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 opt_liberalutf = false; /* Don't check overlong UTF-8 sequences */
+/* define heap sizes **********************************************************/
-bool showmethods = false;
-bool showconstantpool = false;
-bool showutf = false;
+#define HEAP_MAXSIZE 64 * 1024 * 1024; /* default 64MB */
+#define HEAP_STARTSIZE 2 * 1024 * 1024; /* default 2MB */
+#define STACK_SIZE 128 * 1024; /* default 128kB */
-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 */
+#if defined(ENABLE_INTRP)
+u1 *intrp_main_stack;
+#endif
-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 */
+/* CACAO related stuff ********************************************************/
-bool makeinitializations = true;
+bool cacao_initializing;
+bool cacao_exiting;
-bool getloadingtime = false; /* to measure the runtime */
-s8 loadingtime = 0;
-bool getcompilingtime = false; /* compute compile time */
-s8 compilingtime = 0; /* accumulated compile time */
+/* Invocation API variables ***************************************************/
-int has_ext_instr_set = 0; /* has instruction set extensions */
+JavaVM *jvm; /* denotes a Java VM */
+JNIEnv *env; /* pointer to native method interface */
+
+JDK1_1InitArgs vm_args; /* JDK 1.1 VM initialization arguments */
-bool statistics = false;
-bool opt_verify = true; /* true if classfiles should be verified */
+char *bootclasspath; /* contains the boot classpath */
+char *classpath; /* contains the classpath */
-char mainString[256];
-static classinfo *topclass;
+char *mainstring;
+static classinfo *mainclass;
#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 OPT_CLASSPATH 2
-#define OPT_D 3
-#define OPT_MS 4
-#define OPT_MX 5
-#define OPT_VERBOSE1 6
-#define OPT_VERBOSE 7
-#define OPT_VERBOSEGC 8
-#define OPT_VERBOSECALL 9
-#define OPT_NOIEEE 10
-#define OPT_SOFTNULL 11
-#define OPT_TIME 12
-#define OPT_STAT 13
-#define OPT_LOG 14
-#define OPT_CHECK 15
-#define OPT_LOAD 16
-#define OPT_METHOD 17
-#define OPT_SIGNATURE 18
-#define OPT_SHOW 19
-#define OPT_ALL 20
-#define OPT_OLOOP 24
-#define OPT_INLINING 25
-#define OPT_RT 26
-#define OPT_XTA 27
-#define OPT_VTA 28
-#define OPT_VERBOSETC 29
-#define OPT_NOVERIFY 30
-#define OPT_LIBERALUTF 31
+/* 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_VERBOSESPECIFIC 8
+#define OPT_VERBOSECALL 9
+#define OPT_NOIEEE 10
+#define OPT_SOFTNULL 11
+#define OPT_TIME 12
+
+#if defined(STATISTICS)
+#define OPT_STAT 13
+#endif /* defined(STATISTICS) */
+
+#define OPT_LOG 14
+#define OPT_CHECK 15
+#define OPT_LOAD 16
+#define OPT_METHOD 17
+#define OPT_SIGNATURE 18
+#define OPT_SHOW 19
+#define OPT_ALL 20
+#define OPT_OLOOP 24
+#define OPT_INLINING 25
+
+#define STATIC_ANALYSIS
+#if defined(STATIC_ANALYSIS)
+# define OPT_RT 26
+# define OPT_XTA 27
+# define OPT_VTA 28
+#endif /* defined(STATIC_ANALYSIS) */
+
+#define OPT_VERBOSETC 29
+#define OPT_NOVERIFY 30
+#define OPT_LIBERALUTF 31
#define OPT_VERBOSEEXCEPTION 32
-
-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},
- {"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},
+#define OPT_EAGER 33
+
+#if defined(LSRA)
+#define OPT_LSRA 34
+#endif /* defined(LSRA) */
+
+#define OPT_JAR 35
+#define OPT_BOOTCLASSPATH 36
+#define OPT_BOOTCLASSPATH_A 37
+#define OPT_BOOTCLASSPATH_P 38
+#define OPT_VERSION 39
+#define OPT_SHOWVERSION 40
+#define OPT_FULLVERSION 41
+
+#define OPT_HELP 100
+#define OPT_X 101
+
+#define OPT_JIT 102
+#define OPT_INTRP 103
+
+#define OPT_STATIC_SUPERS 104
+#define OPT_TRACE 105
+
+#define OPT_SS 106
+
+#ifdef ENABLE_JVMTI
+#define OPT_DEBUG 107
+#define OPT_AGENTLIB 108
+#define OPT_AGENTPATH 109
+#endif
+
+opt_struct opts[] = {
+ { "classpath", true, OPT_CLASSPATH },
+ { "cp", true, OPT_CLASSPATH },
+ { "D", true, OPT_D },
+ { "noasyncgc", false, OPT_IGNORE },
+ { "noverify", false, OPT_NOVERIFY },
+ { "liberalutf", false, OPT_LIBERALUTF },
+ { "v", false, OPT_VERBOSE1 },
+ { "verbose", false, OPT_VERBOSE },
+ { "verbose:", true, OPT_VERBOSESPECIFIC },
+ { "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 },
+#if defined(STATISTICS)
+ { "stat", false, OPT_STAT },
+#endif
+ { "log", true, OPT_LOG },
+ { "c", true, OPT_CHECK },
+ { "l", false, OPT_LOAD },
+ { "eager", false, OPT_EAGER },
+ { "sig", true, OPT_SIGNATURE },
+ { "all", false, OPT_ALL },
+ { "oloop", false, OPT_OLOOP },
+#ifdef STATIC_ANALYSIS
+ { "rt", false, OPT_RT },
+ { "xta", false, OPT_XTA },
+ { "vta", false, OPT_VTA },
+#endif
+#ifdef LSRA
+ { "lsra", false, OPT_LSRA },
#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}
+ { "jar", false, OPT_JAR },
+ { "version", false, OPT_VERSION },
+ { "showversion", false, OPT_SHOWVERSION },
+ { "fullversion", false, OPT_FULLVERSION },
+ { "help", false, OPT_HELP },
+ { "?", false, OPT_HELP },
+
+ /* interpreter options */
+
+ { "trace", false, OPT_TRACE },
+ { "static-supers", true, OPT_STATIC_SUPERS },
+
+ /* JVMTI Agent Command Line Options */
+#ifdef ENABLE_JVMTI
+ { "agentlib:", true, OPT_AGENTLIB },
+ { "agentpath:", true, OPT_AGENTPATH },
+#endif
+
+ /* X options */
+
+ { "X", false, OPT_X },
+ { "Xjit", false, OPT_JIT },
+ { "Xint", false, OPT_INTRP },
+ { "Xbootclasspath:", true, OPT_BOOTCLASSPATH },
+ { "Xbootclasspath/a:", true, OPT_BOOTCLASSPATH_A },
+ { "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P },
+#ifdef ENABLE_JVMTI
+ { "Xdebug", false, OPT_DEBUG },
+#endif
+ { "Xms", true, OPT_MS },
+ { "Xmx", true, OPT_MX },
+ { "Xss", true, OPT_SS },
+ { "ms", true, OPT_MS },
+ { "mx", true, OPT_MX },
+ { "ss", true, OPT_SS },
+
+ /* keep these at the end of the list */
+
+ { "i", true, OPT_INLINING },
+ { "m", true, OPT_METHOD },
+ { "s", true, OPT_SHOW },
+
+ { NULL, false, 0 }
};
-static int opt_ind = 1;
-static char *opt_arg;
+/* usage ***********************************************************************
-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;
-}
+ Prints the correct usage syntax to stdout.
+*******************************************************************************/
+static void usage(void)
+{
+ printf("Usage: cacao [-options] classname [arguments]\n");
+ printf(" (to run a class file)\n");
+ printf(" cacao [-options] -jar jarfile [arguments]\n");
+ printf(" (to run a standalone jar file)\n\n");
+
+ printf("Java 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(" -D<name>=<value> add an entry to the property list\n");
+ printf(" -verbose[:class|gc|jni] enable specific verbose output\n");
+ printf(" -version print product version and exit\n");
+ printf(" -fullversion print jpackage-compatible product version and exit\n");
+ printf(" -showversion print product version and continue\n");
+ printf(" -help, -? print this help message\n");
+ printf(" -X print help on non-standard Java options\n\n");
+
+#ifdef ENABLE_JVMTI
+ printf(" -agentlib:<agent-lib-name>=<options> library to load containg JVMTI agent\n");
+ printf(" -agentpath:<path-to-agent>=<options> path to library containg JVMTI agent\n");
+#endif
+ printf("CACAO options:\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");
+#if defined(STATISTICS)
+ printf(" -stat detailed compiler statistics\n");
+#endif
+ printf(" -log logfile specify a name for the logfile\n");
+ printf(" -c(heck)b(ounds) don't check array bounds\n");
+ printf(" s(ync) don't check for synchronization\n");
+ printf(" -oloop optimize array accesses in loops\n");
+ printf(" -l don't start the class after loading\n");
+ printf(" -eager perform eager class loading and linking\n");
+ printf(" -all compile all methods, no execution\n");
+ printf(" -m compile only a specific method\n");
+ printf(" -sig specify signature for a specific method\n");
+ printf(" -s(how)a(ssembler) show disassembled listing\n");
+ printf(" c(onstants) show the constant pool\n");
+ printf(" d(atasegment) show data segment listing\n");
+ printf(" e(xceptionstubs) show disassembled exception stubs (only with -sa)\n");
+ printf(" i(ntermediate) show intermediate representation\n");
+ printf(" m(ethods) show class fields and methods\n");
+ printf(" n(ative) show disassembled native stubs\n");
+ printf(" u(tf) show the utf - hash\n");
+ printf(" -i n(line) activate inlining\n");
+ printf(" v(irtual) inline virtual methods (uses/turns rt option on)\n");
+ printf(" e(exception) inline methods with exceptions\n");
+ printf(" p(aramopt) optimize argument renaming\n");
+ printf(" o(utsiders) 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
-/******************** interne Function: print_usage ************************
+ /* exit with error code */
-Prints the correct usage syntax to stdout.
+ exit(1);
+}
-***************************************************************************/
-static void print_usage()
+static void Xusage(void)
{
- 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(" -verboseexception .... write message for each step of stack unwinding\n");
-#ifdef TYPECHECK_VERBOSE
- printf(" -verbosetc ........... write debug messages while typechecking\n");
+#if defined(ENABLE_JIT)
+ printf(" -Xjit JIT mode execution (default)\n");
#endif
-#if defined(__ALPHA__)
- printf(" -noieee .............. don't use ieee compliant arithmetic\n");
+#if defined(ENABLE_INTRP)
+ printf(" -Xint interpreter mode execution\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(" -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(" e ............. inline methods with exceptions\n");
- printf(" p ............. optimize argument renaming\n");
- printf(" o ............. inline methods of foreign classes\n");
- printf(" -rt .................. use rapid type analysis\n");
- printf(" -xta ................. use x type analysis\n");
- printf(" -vta ................. use variable type analysis\n");
+ printf(" -Xbootclasspath:<zip/jar files and directories separated by :>\n");
+ printf(" value is set as bootstrap class path\n");
+ printf(" -Xbootclasspath/a:<zip/jar files and directories separated by :>\n");
+ printf(" value is appended to the bootstrap class path\n");
+ printf(" -Xbootclasspath/p:<zip/jar files and directories separated by :>\n");
+ printf(" value is prepended to the bootstrap class path\n");
+ printf(" -Xms<size> set the initial size of the heap (default: 2MB)\n");
+ printf(" -Xmx<size> set the maximum size of the heap (default: 64MB)\n");
+ printf(" -Xss<size> set the thread stack size (default: 128kB)\n");
+#if defined(ENABLE_JVMTI)
+ printf(" -Xdebug<transport> enable remote debugging\n");
+#endif
+
+ /* exit with error code */
+
+ exit(1);
}
+/* version *********************************************************************
-/***************************** Function: print_times *********************
+ Only prints cacao version information.
- Prints a summary of CPU time usage.
+*******************************************************************************/
-**************************************************************************/
-
-static void print_times()
+static void version(void)
{
- s8 totaltime = getcputime();
- s8 runtime = totaltime - loadingtime - compilingtime;
- char logtext[MAXLOGTEXT];
+ printf("java version \""JAVA_VERSION"\"\n");
+ printf("CACAO version "VERSION"\n");
+
+ printf("Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,\n");
+ printf("R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,\n");
+ printf("C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,\n");
+ printf("Institut f. Computersprachen - TU Wien\n\n");
+
+ printf("This program is free software; you can redistribute it and/or\n");
+ printf("modify it under the terms of the GNU General Public License as\n");
+ printf("published by the Free Software Foundation; either version 2, or (at\n");
+ printf("your option) any later version.\n\n");
+
+ printf("This program is distributed in the hope that it will be useful, but\n");
+ printf("WITHOUT ANY WARRANTY; without even the implied warranty of\n");
+ printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n");
+ printf("General Public License for more details.\n");
+}
-#if defined(__I386__) || defined(__POWERPC__)
- 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__) || defined(__POWERPC__)
- sprintf(logtext, "Time for compiling code: %lld secs, %lld millis",
-#else
- sprintf(logtext, "Time for compiling code: %ld secs, %ld millis",
-#endif
- compilingtime / 1000000, (compilingtime % 1000000) / 1000);
- log_text(logtext);
+/* fullversion *****************************************************************
-#if defined(__I386__) || defined(__POWERPC__)
- 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);
+ Prints a Sun compatible version information (required e.g. by
+ jpackage, www.jpackage.org).
-#if defined(__I386__) || defined(__POWERPC__)
- 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);
+*******************************************************************************/
+
+static void fullversion(void)
+{
+ printf("java full version \"cacao-"JAVA_VERSION"\"\n");
+
+ /* exit normally */
+
+ exit(0);
}
+#ifdef TYPECHECK_STATISTICS
+void typecheck_print_statistics(FILE *file);
+#endif
+/* setup_debugger_process *****************************************************
+ Helper function to start JDWP threads
+*******************************************************************************/
+#if defined(ENABLE_JVMTI)
-/***************************** Function: print_stats *********************
+static void setup_debugger_process(char* transport) {
+ java_objectheader *o;
+ methodinfo *m;
+ java_lang_String *s;
- outputs detailed compiler statistics
+ /* new gnu.classpath.jdwp.Jdwp() */
+ mainclass =
+ load_class_from_sysloader(utf_new_char("gnu.classpath.jdwp.Jdwp"));
+ if (!mainclass)
+ throw_main_exception_exit();
-**************************************************************************/
+ o = builtin_new(mainclass);
-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);
+ if (!o)
+ throw_main_exception_exit();
+
+ m = class_resolveclassmethod(mainclass,
+ utf_init,
+ utf_java_lang_String__void,
+ class_java_lang_Object,
+ true);
+ if (!m)
+ throw_main_exception_exit();
+
+ asm_calljavafunction(m, o, NULL, NULL, NULL);
+
+ /* configure(transport,NULL) */
+ m = class_resolveclassmethod(
+ mainclass, utf_new_char("configure"),
+ utf_new_char("(Ljava/lang/String;Ljava/lang/Thread;)V"),
+ class_java_lang_Object,
+ false);
+
+
+ s = javastring_new_char(transport);
+ asm_calljavafunction(m, o, s, NULL, NULL);
+ if (!m)
+ throw_main_exception_exit();
+
+ /* _doInitialization */
+ m = class_resolveclassmethod(mainclass,
+ utf_new_char("_doInitialization"),
+ utf_new_char("()V"),
+ mainclass,
+ false);
+
+ if (!m)
+ throw_main_exception_exit();
+
+ asm_calljavafunction(m, o, NULL, NULL, NULL);
}
+#endif
+
+/* getmainclassfromjar *********************************************************
-/********** Function: class_compile_methods (debugging only) ********/
+ Gets the name of the main class form a JAR's manifest file.
-void class_compile_methods()
+*******************************************************************************/
+
+static char *getmainclassnamefromjar(char *mainstring)
{
- int i;
- classinfo *c;
- methodinfo *m;
+ classinfo *c;
+ java_objectheader *o;
+ methodinfo *m;
+ java_lang_String *s;
+
+ c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
+
+ if (!c)
+ throw_main_exception_exit();
- 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);
- }
-}
+ /* create JarFile object */
-#ifdef TYPECHECK_STATISTICS
-void typecheck_print_statistics(FILE *file);
-#endif
+ o = builtin_new(c);
-/*
- * void exit_handler(void)
- * -----------------------
- * The exit_handler function is called upon program termination to shutdown
- * the various subsystems and release the resources allocated to the VM.
- */
-void exit_handler(void)
-{
- /********************* Print debug tables ************************/
-
- if (showmethods) class_showmethods(topclass);
- if (showconstantpool) class_showconstantpool(topclass);
- if (showutf) utf_show();
+ if (!o)
+ throw_main_exception_exit();
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
- clear_thread_flags(); /* restores standard file descriptor
- flags */
-#endif
- /************************ Free all resources *******************/
+ m = class_resolveclassmethod(c,
+ utf_init,
+ utf_java_lang_String__void,
+ class_java_lang_Object,
+ true);
- heap_close(); /* must be called before compiler_close and
- loader_close because finalization occurs
- here */
+ if (!m)
+ throw_main_exception_exit();
- loader_close();
- tables_close(literalstring_free);
+ s = javastring_new_char(mainstring);
- if (verbose || getcompilingtime || statistics) {
- log_text("CACAO terminated");
- if (statistics) {
- print_stats();
-#ifdef TYPECHECK_STATISTICS
- typecheck_print_statistics(get_logfile());
-#endif
- }
- if (getcompilingtime)
- print_times();
- mem_usagelog(1);
+ asm_calljavafunction(m, o, s, NULL, NULL);
+
+ if (*exceptionptr)
+ throw_main_exception_exit();
+
+ /* get manifest object */
+
+ m = class_resolveclassmethod(c,
+ utf_new_char("getManifest"),
+ utf_new_char("()Ljava/util/jar/Manifest;"),
+ class_java_lang_Object,
+ true);
+
+ if (!m)
+ throw_main_exception_exit();
+
+ o = asm_calljavafunction(m, o, NULL, NULL, NULL);
+
+ if (!o) {
+ fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
+ cacao_exit(1);
}
+
+
+ /* get Main Attributes */
+
+ m = class_resolveclassmethod(o->vftbl->class,
+ utf_new_char("getMainAttributes"),
+ utf_new_char("()Ljava/util/jar/Attributes;"),
+ class_java_lang_Object,
+ true);
+
+ if (!m)
+ throw_main_exception_exit();
+
+ o = asm_calljavafunction(m, o, NULL, NULL, NULL);
+
+ if (!o) {
+ fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
+ cacao_exit(1);
+ }
+
+
+ /* get property Main-Class */
+
+ m = class_resolveclassmethod(o->vftbl->class,
+ utf_new_char("getValue"),
+ utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
+ class_java_lang_Object,
+ true);
+
+ if (!m)
+ throw_main_exception_exit();
+
+ s = javastring_new_char("Main-Class");
+
+ o = asm_calljavafunction(m, o, s, NULL, NULL);
+
+ if (!o)
+ throw_main_exception_exit();
+
+ return javastring_tochar(o);
}
-/************************** Function: main *******************************
+void exit_handler(void);
+
+
+/* main ************************************************************************
The main program.
-**************************************************************************/
+*******************************************************************************/
int main(int argc, char **argv)
{
s4 i, j;
- char *cp;
void *dummy;
- /********** interne (nur fuer main relevante Optionen) **************/
+ /* local variables ********************************************************/
char logfilename[200] = "";
- u4 heapsize = 64000000;
- u4 heapstartsize = 200000;
- char classpath[500] = ".";
+ u4 heapmaxsize;
+ u4 heapstartsize;
+ char *cp;
+ s4 cplen;
bool startit = true;
char *specificmethodname = NULL;
char *specificsignature = NULL;
+ bool jar = false;
+#if defined(ENABLE_JVMTI)
+ bool dbg = false;
+ char *transport;
+ int waitval;
+#endif
+
#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");
+
+ /* initialize global variables */
+
+ cacao_exiting = false;
+
/************ Collect info from the environment ************************/
+ /* set the bootclasspath */
+
+ cp = getenv("BOOTCLASSPATH");
+ if (cp) {
+ bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
+ strcpy(bootclasspath, cp);
+
+ } else {
+ cplen = strlen(CACAO_INSTALL_PREFIX) + strlen(CACAO_VM_ZIP_PATH) +
+ strlen(":") +
+ strlen(CLASSPATH_INSTALL_DIR) +
+ strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
+ strlen("0");
+
+ bootclasspath = MNEW(char, cplen);
+ strcpy(bootclasspath, CACAO_INSTALL_PREFIX);
+ strcat(bootclasspath, CACAO_VM_ZIP_PATH);
+ strcat(bootclasspath, ":");
+ strcat(bootclasspath, CLASSPATH_INSTALL_DIR);
+ strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
+ }
+
+
+ /* set the classpath */
+
cp = getenv("CLASSPATH");
if (cp) {
- strcpy(classpath, cp);
+ classpath = MNEW(char, strlen(cp) + strlen("0"));
+ strcat(classpath, cp);
+
+ } else {
+ classpath = MNEW(char, strlen(".") + strlen("0"));
+ strcpy(classpath, ".");
}
+
/***************** Interpret the command line *****************/
checknull = false;
opt_noieee = false;
- while ((i = get_opt(argc, argv)) != OPT_DONE) {
+ heapmaxsize = HEAP_MAXSIZE;
+ heapstartsize = HEAP_STARTSIZE;
+ opt_stacksize = STACK_SIZE;
+
+ 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_BOOTCLASSPATH:
+ /* Forget default bootclasspath and set the argument as new boot */
+ /* classpath. */
+ MFREE(bootclasspath, char, strlen(bootclasspath));
+
+ bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
+ strcpy(bootclasspath, opt_arg);
break;
-
+
+ case OPT_BOOTCLASSPATH_A:
+ /* append to end of bootclasspath */
+ cplen = strlen(bootclasspath);
+
+ bootclasspath = MREALLOC(bootclasspath,
+ char,
+ cplen,
+ cplen + strlen(":") +
+ strlen(opt_arg) + strlen("0"));
+
+ strcat(bootclasspath, ":");
+ strcat(bootclasspath, opt_arg);
+ break;
+
+ case OPT_BOOTCLASSPATH_P:
+ /* prepend in front of bootclasspath */
+ cp = bootclasspath;
+ cplen = strlen(cp);
+
+ bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
+ cplen + strlen("0"));
+
+ strcpy(bootclasspath, opt_arg);
+ strcat(bootclasspath, ":");
+ strcat(bootclasspath, cp);
+
+ MFREE(cp, char, cplen);
+ break;
+
+ case OPT_CLASSPATH:
+ /* forget old classpath and set the argument as new classpath */
+ MFREE(classpath, char, strlen(classpath));
+
+ classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
+ strcpy(classpath, opt_arg);
+ break;
+
+ case OPT_JAR:
+ jar = true;
+ break;
+
+#if defined(ENABLE_JVMTI)
+ case OPT_DEBUG:
+ dbg = true;
+ transport = opt_arg;
+ break;
+
+ case OPT_AGENTPATH:
+ case OPT_AGENTLIB:
+ set_jvmti_phase(JVMTI_PHASE_ONLOAD);
+ agentload(opt_arg);
+ set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
+ break;
+#endif
+
case OPT_D:
{
- int n;
- int l = strlen(opt_arg);
- for (n = 0; n < l; n++) {
- if (opt_arg[n] == '=') {
- opt_arg[n] = '\0';
- attach_property(opt_arg, opt_arg + n + 1);
+ for (j = 0; j < strlen(opt_arg); j++) {
+ if (opt_arg[j] == '=') {
+ opt_arg[j] = '\0';
+ create_property(opt_arg, opt_arg + j + 1);
goto didit;
}
}
- print_usage();
- exit(10);
+
+ /* if no '=' is given, just create an empty property */
+ create_property(opt_arg, "");
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);
+ case OPT_MS:
+ case OPT_SS:
+ {
+ 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 if (i == OPT_MS)
+ heapstartsize = j;
+ else
+ opt_stacksize = 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;
+
+ case OPT_VERBOSESPECIFIC:
+ if (strcmp("class", opt_arg) == 0)
+ opt_verboseclass = true;
+
+ else if (strcmp("gc", opt_arg) == 0)
+ opt_verbosegc = true;
+
+ else if (strcmp("jni", opt_arg) == 0)
+ opt_verbosejni = true;
break;
- case OPT_VERBOSEGC:
- collectverbose = true;
+ case OPT_VERBOSEEXCEPTION:
+ opt_verboseexception = true;
break;
#ifdef TYPECHECK_VERBOSE
case OPT_VERBOSECALL:
runverbose = true;
break;
-
+
+ case OPT_VERSION:
+ version();
+ exit(0);
+ break;
+
+ case OPT_FULLVERSION:
+ fullversion();
+ break;
+
+ case OPT_SHOWVERSION:
+ version();
+ break;
+
case OPT_NOIEEE:
opt_noieee = true;
break;
getloadingtime = true;
break;
+#if defined(STATISTICS)
case OPT_STAT:
- statistics = true;
+ opt_stat = true;
break;
+#endif
case OPT_LOG:
strcpy(logfilename, opt_arg);
checksync = false;
break;
default:
- print_usage();
- exit(10);
+ usage();
}
}
break;
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;
for (j = 0; j < strlen(opt_arg); j++) {
switch (opt_arg[j]) {
case 'a':
- showdisassemble = true;
- compileverbose=true;
+ opt_showdisassemble = true;
+ compileverbose = true;
break;
case 'c':
showconstantpool = true;
break;
case 'd':
- showddatasegment = true;
+ opt_showddatasegment = true;
+ break;
+ case 'e':
+ opt_showexceptionstubs = true;
break;
case 'i':
- showintermediate = true;
+ opt_showintermediate = true;
compileverbose = true;
break;
case 'm':
showmethods = true;
break;
+ case 'n':
+ opt_shownativestub = true;
+ break;
case 'u':
showutf = true;
break;
default:
- print_usage();
- exit(10);
+ usage();
}
}
break;
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;
inlineoutsiders = true;
break;
default:
- print_usage();
- exit(10);
+ usage();
}
}
break;
+#ifdef STATIC_ANALYSIS
case OPT_RT:
- opt_rt = true;
+ opt_rt = true; /* default for inlining */
break;
case OPT_XTA:
- opt_xta = false; /**not yet **/
+ opt_xta = true; /* in test currently */
break;
case OPT_VTA:
+ printf("\nVTA is not yet available\n");
+ opt_vta = false;
/***opt_vta = true; not yet **/
break;
+#endif
+
+#ifdef LSRA
+ case OPT_LSRA:
+ opt_lsra = true;
+ break;
+#endif
+
+ case OPT_HELP:
+ usage();
+ break;
+
+ case OPT_X:
+ Xusage();
+ break;
+
+ case OPT_JIT:
+#if defined(ENABLE_JIT)
+ opt_jit = true;
+#else
+ printf("-Xjit option not enabled.\n");
+ exit(1);
+#endif
+ break;
+
+ case OPT_INTRP:
+#if defined(ENABLE_INTRP)
+ opt_intrp = true;
+#else
+ printf("-Xint option not enabled.\n");
+ exit(1);
+#endif
+ break;
+
+ case OPT_STATIC_SUPERS:
+ opt_static_supers = atoi(opt_arg);
+ break;
+
+ case OPT_TRACE:
+ vm_debug = true;
+ break;
default:
- print_usage();
- exit(10);
+ printf("Unknown option: %s\n", argv[opt_ind]);
+ usage();
}
}
-
-
- if (opt_ind >= argc) {
- print_usage();
- exit(10);
- }
- 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 */
- }
+ if (opt_ind >= argc)
+ usage();
+
+
+ /* transform dots into slashes in the class name */
- strcpy(mainString,cp);
+ mainstring = argv[opt_ind++];
+
+ if (!jar) {
+ /* do not mangle jar filename */
+
+ for (i = strlen(mainstring) - 1; i >= 0; i--) {
+ if (mainstring[i] == '.') mainstring[i] = '/';
+ }
+ } else {
+ /* put jarfile in classpath */
+
+ cp = classpath;
+
+ classpath = MNEW(char, strlen(mainstring) + strlen(":") +
+ strlen(classpath) + strlen("0"));
+
+ strcpy(classpath, mainstring);
+ strcat(classpath, ":");
+ strcat(classpath, cp);
+
+ MFREE(cp, char, strlen(cp));
+ }
/**************************** Program start *****************************/
+
log_init(logfilename);
- if (verbose) {
+
+ if (opt_verbose)
log_text("CACAO started -------------------------------------------------------");
- }
- heap_init(heapsize, heapstartsize, &dummy);
+ /* initialize JavaVM */
+
+ vm_args.version = 0x00010001; /* New in 1.1.2: VM version */
+
+ /* Get the default initialization arguments and set the class path */
+
+ JNI_GetDefaultJavaVMInitArgs(&vm_args);
+
+ vm_args.minHeapSize = heapstartsize;
+ vm_args.maxHeapSize = heapmaxsize;
+
+ vm_args.classpath = classpath;
+
+ /* load and initialize a Java VM, return a JNI interface pointer in env */
+
+ JNI_CreateJavaVM(&jvm, &env, &vm_args);
+
+#if defined(ENABLE_JVMTI)
+ set_jvmti_phase(JVMTI_PHASE_START);
+#endif
+
+ /* initialize the garbage collector */
+
+ gc_init(heapmaxsize, heapstartsize);
+
+#if defined(ENABLE_INTRP)
+ /* allocate main thread stack */
+
+ if (opt_intrp) {
+ intrp_main_stack = (u1 *) alloca(opt_stacksize);
+ MSET(intrp_main_stack, 0, u1, opt_stacksize);
+ }
+#endif
- native_setclasspath(classpath);
-
tables_init();
- suck_init(classpath);
+
+ /* initialize the loader with bootclasspath */
+
+ suck_init(bootclasspath);
+
+ cacao_initializing = true;
+
+#if defined(USE_THREADS)
+#if defined(NATIVE_THREADS)
+ threads_preinit();
+#endif
+ initLocks();
+#endif
+
+ /* initialize the memory subsystem (must be done _after_
+ threads_preinit) */
+
+ if (!memory_init())
+ throw_main_exception_exit();
+
+ /* initialize the finalizer stuff: lock, linked list (must be done
+ _after_ threads_preinit) */
+
+ if (!finalizer_init())
+ throw_main_exception_exit();
+
+ /* install architecture dependent signal handler used for exceptions */
+
+ signal_init();
+
+ /* initialize the codegen subsystems */
+
+ codegen_init();
+
+ /* initializes jit compiler */
jit_init();
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- initThreadsEarly();
+ /* machine dependent initialization */
+
+ md_init();
+
+ /* initialize some cacao subsystems */
+
+ utf8_init();
+
+ if (!loader_init((u1 *) &dummy))
+ throw_main_exception_exit();
+
+ if (!linker_init())
+ throw_main_exception_exit();
+
+ if (!native_init())
+ throw_main_exception_exit();
+
+ if (!exceptions_init())
+ throw_main_exception_exit();
+
+ if (!builtin_init())
+ throw_main_exception_exit();
+
+#if defined(USE_THREADS)
+ if (!threads_init((u1 *) &dummy))
+ throw_main_exception_exit();
#endif
- loader_init((u1 *) &dummy);
+ /* 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!!! */
- native_loadclasses();
+ if (!initialize_class(class_java_lang_System))
+ throw_main_exception_exit();
- /* initialize the garbage collector */
- gc_init();
+ /* JNI init creates a Java object (this means running Java code) */
+
+ if (!jni_init())
+ throw_main_exception_exit();
#if defined(USE_THREADS)
- initThreads((u1*) &dummy);
+ /* finally, start the finalizer thread */
+
+ if (!finalizer_start_thread())
+ throw_main_exception_exit();
#endif
- /*********************** Load JAVA classes ***************************/
-
- /*printf("-------------------->%s\n",cp);*/
- topclass = loader_load(utf_new_char(cp));
- /*class_showmethods(topclass); */
-
- if (*exceptionptr) {
- printf("Exception in thread \"main\" ");
- utf_display_classname((*exceptionptr)->vftbl->class->name);
- printf(": ");
- utf_display(javastring_toutf(((java_lang_Throwable *) *exceptionptr)->detailMessage, false));
- printf("\n");
-
- *exceptionptr = NULL;
- }
+ cacao_initializing = false;
- if (topclass == 0) {
- /* should we print something out? we already have the exception */
- exit(1);
- }
- /************************* Start worker routines ********************/
+ /* start worker routines **************************************************/
if (startit) {
- methodinfo *mainmethod;
+ classinfo *mainclass; /* java/lang/Class */
+ methodinfo *m;
java_objectarray *a;
+ s4 status;
+
+ /* set return value to OK */
+
+ status = 0;
+
+ if (jar) {
+ /* open jar file with java.util.jar.JarFile */
+ mainstring = getmainclassnamefromjar(mainstring);
+ }
+
+ /* load the main class */
+
+ if (!(mainclass = load_class_from_sysloader(utf_new_char(mainstring))))
+ throw_main_exception_exit();
-/* heap_addreference((void**) &a); */
+ /* error loading class, clear exceptionptr for new exception */
- mainmethod = class_findmethod(topclass,
- utf_new_char("main"),
- utf_new_char("([Ljava/lang/String;)V")
- );
+ if (*exceptionptr || !mainclass) {
+/* *exceptionptr = NULL; */
+
+/* *exceptionptr = */
+/* new_exception_message(string_java_lang_NoClassDefFoundError, */
+/* mainstring); */
+ throw_main_exception_exit();
+ }
+
+ /* find the `main' method of the main class */
+
+ m = class_resolveclassmethod(mainclass,
+ utf_new_char("main"),
+ utf_new_char("([Ljava/lang/String;)V"),
+ class_java_lang_Object,
+ false);
+
+ if (*exceptionptr) {
+ throw_main_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);
+
+ if (!m || !(m->flags & ACC_STATIC)) {
+ *exceptionptr = NULL;
+
+ *exceptionptr =
+ new_exception_message(string_java_lang_NoSuchMethodError,
+ "main");
+ throw_main_exception_exit();
}
+ /* build argument array */
+
a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
for (i = opt_ind; i < argc; i++) {
a->data[i - opt_ind] =
#endif
/*class_showmethods(currentThread->group->header.vftbl->class); */
- *threadrootmethod=mainmethod;
- /* here we go... */
- asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
-
- if (*exceptionptr) {
- methodinfo *main_unhandled_print=class_resolvemethod_approx((*exceptionptr)->vftbl->class,
- utf_new_char("printStackTrace"),
- utf_new_char("()V"));
- if (main_unhandled_print) {
- java_objectheader *exo=*exceptionptr;
- *exceptionptr=0;
- asm_calljavafunction(main_unhandled_print,exo,NULL,NULL,NULL);
+#if defined(ENABLE_JVMTI) && defined(NATIVE_THREADS)
+ if(dbg) {
+ debuggee = fork();
+ if (debuggee == (-1)) {
+ log_text("fork error");
+ exit(1);
} else {
- printf("Exception in thread \"main\" ");
- utf_display_classname((*exceptionptr)->vftbl->class->name);
+ if (debuggee == 0) {
+ /* child: allow helper process to trace us */
+ if (TRACEME != 0) exit(0);
+
+ /* give parent/helper debugger process control */
+ kill(0, SIGTRAP); /* do we need this at this stage ? */
+
+ /* continue with normal startup */
- /* do we have a detail message? */
- if (((java_lang_Throwable *) *exceptionptr)->detailMessage) {
- printf(": ");
- utf_display(javastring_toutf(((java_lang_Throwable *) *exceptionptr)->detailMessage, false));
+ } else {
+
+ /* parent/helper debugger process */
+ wait(&waitval);
+
+ remotedbgjvmtienv = new_jvmtienv();
+ /* set eventcallbacks */
+ if (JVMTI_ERROR_NONE ==
+ remotedbgjvmtienv->
+ SetEventCallbacks(remotedbgjvmtienv,
+ &jvmti_jdwp_EventCallbacks,
+ sizeof(jvmti_jdwp_EventCallbacks))){
+ log_text("unable to setup event callbacks");
+ cacao_exit(1);
+ }
+
+ /* setup listening process (JDWP) */
+ setup_debugger_process(transport);
+
+ /* start to be debugged program */
+ CONT(debuggee);
+
+ /* exit debugger process - todo: cleanup */
+ joinAllThreads();
+ cacao_exit(0);
}
- printf("\n");
}
}
+ else
+ debuggee= -1;
+
+#endif
+ /* here we go... */
+
+ asm_calljavafunction(m, 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);
- fprintf(stderr, "still here\n");
#endif
#endif
- exit(0);
+
+ /* now exit the JavaVM */
+
+/* (*jvm)->DestroyJavaVM(jvm); */
+
+ cacao_exit(status);
}
/************* If requested, compile all methods ********************/
if (compileall) {
- class_compile_methods();
+ classinfo *c;
+ methodinfo *m;
+ u4 slot;
+ s4 i;
+ classcache_name_entry *nmen;
+ classcache_class_entry *clsen;
+
+ /* create all classes found in the classpath */
+ /* XXX currently only works with zip/jar's */
+
+ loader_load_all_classes();
+
+ /* link all classes */
+
+ for (slot = 0; slot < classcache_hash.size; slot++) {
+ nmen = (classcache_name_entry *) classcache_hash.ptr[slot];
+
+ for (; nmen; nmen = nmen->hashlink) {
+ /* iterate over all class entries */
+
+ for (clsen = nmen->classes; clsen; clsen = clsen->next) {
+ c = clsen->classobj;
+
+ if (!c)
+ continue;
+
+ assert(c);
+ assert(c->loaded);
+ /*utf_fprint_classname(stderr,c->name);fprintf(stderr,"\n");*/
+
+ if (!c->linked)
+ if (!link_class(c))
+ throw_main_exception_exit();
+
+ /* compile all class methods */
+ for (i = 0; i < c->methodscount; i++) {
+ m = &(c->methods[i]);
+ if (m->jcode) {
+ /*fprintf(stderr," compiling:");utf_fprint(stderr,m->name);fprintf(stderr,"\n");*/
+ (void) jit_compile(m);
+ }
+ }
+ }
+ }
+ }
}
if (specificmethodname) {
methodinfo *m;
+
+ /* create, load and link the main class */
+
+ if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
+ throw_main_exception_exit();
+
+ if (!link_class(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 ******************************************************************
+
+ Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
-/************************************ Shutdown function *********************************
+*******************************************************************************/
+
+void cacao_exit(s4 status)
+{
+ methodinfo *m;
+
+ assert(class_java_lang_System);
+ assert(class_java_lang_System->loaded);
+
+#if defined(ENABLE_JVMTI)
+ set_jvmti_phase(JVMTI_PHASE_DEAD);
+ agentunload();
+#endif
+
+ if (!link_class(class_java_lang_System))
+ throw_main_exception_exit();
+
+ /* signal that we are exiting */
+
+ cacao_exiting = true;
+
+ /* call java.lang.System.exit(I)V */
+
+ m = class_resolveclassmethod(class_java_lang_System,
+ utf_new_char("exit"),
+ utf_int__void,
+ class_java_lang_Object,
+ true);
+
+ if (!m)
+ throw_main_exception_exit();
+
+ /* call the exit function with passed exit status */
+
+ /* both inlinevirtual and outsiders not allowed on exit */
+ /* not sure if permanant or temp restriction */
+ if (inlinevirtuals) inlineoutsiders = false;
+
+ asm_calljavafunction(m, (void *) (ptrint) status, NULL, NULL, NULL);
+
+ /* this should never happen */
+
+ if (*exceptionptr)
+ throw_exception_exit();
+
+ throw_cacao_exception_exit(string_java_lang_InternalError,
+ "System.exit(I)V returned without exception");
+}
+
+
+/*************************** Shutdown function *********************************
Terminates the system immediately without freeing memory explicitly (to be
used only for abnormal termination)
-*****************************************************************************************/
+*******************************************************************************/
void cacao_shutdown(s4 status)
{
- /**** RTAprint ***/
- if (verbose || getcompilingtime || statistics) {
- log_text ("CACAO terminated by shutdown");
- if (statistics)
+#if defined(ENABLE_JVMTI)
+ agentunload();
+#endif
+
+ if (opt_verbose || getcompilingtime || opt_stat) {
+ log_text("CACAO terminated by shutdown");
+ dolog("Exit status: %d\n", (s4) status);
+ }
+
+ exit(status);
+}
+
+
+/* exit_handler ****************************************************************
+
+ The exit_handler function is called upon program termination.
+
+ ATTENTION: Don't free system resources here! Some threads may still
+ be running as this is called from VMRuntime.exit(). The OS does the
+ cleanup for us.
+
+*******************************************************************************/
+
+void exit_handler(void)
+{
+ /********************* Print debug tables ************************/
+
+ if (showmethods) class_showmethods(mainclass);
+ if (showconstantpool) class_showconstantpool(mainclass);
+ if (showutf) utf_show();
+
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
+ clear_thread_flags(); /* restores standard file descriptor
+ flags */
+#endif
+
+ if (opt_verbose || getcompilingtime || opt_stat) {
+ log_text("CACAO terminated");
+
+#if defined(STATISTICS)
+ if (opt_stat) {
print_stats();
+#ifdef TYPECHECK_STATISTICS
+ typecheck_print_statistics(get_logfile());
+#endif
+ }
+
+ mem_usagelog(1);
+
if (getcompilingtime)
print_times();
- mem_usagelog(0);
- dolog("Exit status: %d\n", (int) status);
+#endif
}
-
- exit(status);
+ /* vm_print_profile(stderr);*/
}