1 /* main.c - contains main() and variables for the global options
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Reinhard Grafl
34 This module does the following tasks:
35 - Command line option handling
36 - Calling initialization routines
37 - Calling the class loader
38 - Running the main method
40 $Id: cacao.c 557 2003-11-02 22:51:59Z twisti $
53 #include "threads/thread.h"
54 #include "toolbox/loging.h"
55 #include "parseRTstats.h"
58 bool compileall = false;
61 static bool showmethods = false;
62 static bool showconstantpool = false;
63 static bool showutf = false;
64 static classinfo *topclass;
67 void **stackbottom = 0;
71 /* internal function: get_opt *************************************************
73 decodes the next command line option
75 ******************************************************************************/
81 #define OPT_CLASSPATH 2
85 #define OPT_VERBOSE1 6
87 #define OPT_VERBOSEGC 8
88 #define OPT_VERBOSECALL 9
90 #define OPT_SOFTNULL 11
97 #define OPT_SIGNATURE 18
101 #define OPT_INLINING 25
107 struct {char *name; bool arg; int value;} opts[] = {
108 {"classpath", true, OPT_CLASSPATH},
110 {"ms", true, OPT_MS},
111 {"mx", true, OPT_MX},
112 {"noasyncgc", false, OPT_IGNORE},
113 {"noverify", false, OPT_IGNORE},
114 {"oss", true, OPT_IGNORE},
115 {"ss", true, OPT_IGNORE},
116 {"v", false, OPT_VERBOSE1},
117 {"verbose", false, OPT_VERBOSE},
118 {"verbosegc", false, OPT_VERBOSEGC},
119 {"verbosecall", false, OPT_VERBOSECALL},
120 {"noieee", false, OPT_NOIEEE},
121 {"softnull", false, OPT_SOFTNULL},
122 {"time", false, OPT_TIME},
123 {"stat", false, OPT_STAT},
124 {"log", true, OPT_LOG},
125 {"c", true, OPT_CHECK},
126 {"l", false, OPT_LOAD},
127 {"m", true, OPT_METHOD},
128 {"sig", true, OPT_SIGNATURE},
129 {"s", true, OPT_SHOW},
130 {"all", false, OPT_ALL},
131 {"oloop", false, OPT_OLOOP},
132 {"i", true, OPT_INLINING},
133 {"rt", false, OPT_RT},
134 {"xta", false, OPT_XTA},
135 {"vta", false, OPT_VTA},
139 static int opt_ind = 1;
140 static char *opt_arg;
142 static int get_opt (int argc, char **argv)
147 if (opt_ind >= argc) return OPT_DONE;
150 if (a[0] != '-') return OPT_DONE;
152 for (i=0; opts[i].name; i++) {
154 if (strcmp(a+1, opts[i].name) == 0) { /* boolean option found */
156 return opts[i].value;
160 if (strcmp(a+1, opts[i].name) == 0) { /* parameter option found */
162 if (opt_ind < argc) {
163 opt_arg = argv[opt_ind];
165 return opts[i].value;
170 size_t l = strlen(opts[i].name);
171 if (strlen(a+1) > l) {
172 if (memcmp (a+1, opts[i].name, l)==0) {
175 return opts[i].value;
188 /******************** interne Function: print_usage ************************
190 Prints the correct usage syntax to stdout.
192 ***************************************************************************/
194 static void print_usage()
196 printf("USAGE: cacao [options] classname [program arguments]\n");
197 printf("Options:\n");
198 printf(" -classpath path ...... specify a path to look for classes\n");
199 printf(" -Dpropertyname=value . add an entry to the property list\n");
200 printf(" -mx maxmem[k|m] ...... specify the size for the heap\n");
201 printf(" -ms initmem[k|m] ..... specify the initial size for the heap\n");
202 printf(" -v ................... write state-information\n");
203 printf(" -verbose ............. write more information\n");
204 printf(" -verbosegc ........... write message for each GC\n");
205 printf(" -verbosecall ......... write message for each call\n");
206 #if defined(__ALPHA__)
207 printf(" -noieee .............. don't use ieee compliant arithmetic\n");
209 printf(" -softnull ............ use software nullpointer check\n");
210 printf(" -time ................ measure the runtime\n");
211 printf(" -stat ................ detailed compiler statistics\n");
212 printf(" -log logfile ......... specify a name for the logfile\n");
213 printf(" -c(heck)b(ounds) ..... don't check array bounds\n");
214 printf(" s(ync) ....... don't check for synchronization\n");
215 printf(" -oloop ............... optimize array accesses in loops\n");
216 printf(" -l ................... don't start the class after loading\n");
217 printf(" -all ................. compile all methods, no execution\n");
218 printf(" -m ................... compile only a specific method\n");
219 printf(" -sig ................. specify signature for a specific method\n");
220 printf(" -s(how)a(ssembler) ... show disassembled listing\n");
221 printf(" c(onstants) ... show the constant pool\n");
222 printf(" d(atasegment).. show data segment listing\n");
223 printf(" i(ntermediate). show intermediate representation\n");
224 printf(" m(ethods)...... show class fields and methods\n");
225 printf(" u(tf) ......... show the utf - hash\n");
226 printf(" -i n ............. activate inlining\n");
227 printf(" v ............. inline virtual methods\n");
228 printf(" e ............. inline methods with exceptions\n");
229 printf(" p ............. optimize argument renaming\n");
230 printf(" o ............. inline methods of foreign classes\n");
231 printf(" -rt .................. use rapid type analysis\n");
232 printf(" -xta ................. use x type analysis\n");
233 printf(" -vta ................. use variable type analysis\n");
238 /***************************** Function: print_times *********************
240 Prints a summary of CPU time usage.
242 **************************************************************************/
244 static void print_times()
246 long int totaltime = getcputime();
247 long int runtime = totaltime - loadingtime - compilingtime;
249 sprintf(logtext, "Time for loading classes: %ld secs, %ld millis",
250 loadingtime / 1000000, (loadingtime % 1000000) / 1000);
252 sprintf(logtext, "Time for compiling code: %ld secs, %ld millis",
253 compilingtime / 1000000, (compilingtime % 1000000) / 1000);
255 sprintf(logtext, "Time for running program: %ld secs, %ld millis",
256 runtime / 1000000, (runtime % 1000000) / 1000);
258 sprintf(logtext, "Total time: %ld secs, %ld millis",
259 totaltime / 1000000, (totaltime % 1000000) / 1000);
268 /***************************** Function: print_stats *********************
270 outputs detailed compiler statistics
272 **************************************************************************/
274 static void print_stats()
276 sprintf(logtext, "Number of JitCompiler Calls: %d", count_jit_calls);
278 sprintf(logtext, "Number of compiled Methods: %d", count_methods);
280 sprintf(logtext, "Number of max basic blocks per method: %d", count_max_basic_blocks);
282 sprintf(logtext, "Number of compiled basic blocks: %d", count_basic_blocks);
284 sprintf(logtext, "Number of max JavaVM-Instructions per method: %d", count_max_javainstr);
286 sprintf(logtext, "Number of compiled JavaVM-Instructions: %d", count_javainstr);
288 sprintf(logtext, "Size of compiled JavaVM-Instructions: %d(%d)", count_javacodesize,
289 count_javacodesize - count_methods * 18);
291 sprintf(logtext, "Size of compiled Exception Tables: %d", count_javaexcsize);
293 sprintf(logtext, "Value of extended instruction set var: %d", has_ext_instr_set);
295 sprintf(logtext, "Number of Machine-Instructions: %d", count_code_len >> 2);
297 sprintf(logtext, "Number of Spills: %d", count_spills);
299 sprintf(logtext, "Number of Activ Pseudocommands: %5d", count_pcmd_activ);
301 sprintf(logtext, "Number of Drop Pseudocommands: %5d", count_pcmd_drop);
303 sprintf(logtext, "Number of Const Pseudocommands: %5d (zero:%5d)", count_pcmd_load, count_pcmd_zero);
305 sprintf(logtext, "Number of ConstAlu Pseudocommands: %5d (cmp: %5d, store:%5d)", count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
307 sprintf(logtext, "Number of Move Pseudocommands: %5d", count_pcmd_move);
309 sprintf(logtext, "Number of Load Pseudocommands: %5d", count_load_instruction);
311 sprintf(logtext, "Number of Store Pseudocommands: %5d (combined: %5d)", count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
313 sprintf(logtext, "Number of OP Pseudocommands: %5d", count_pcmd_op);
315 sprintf(logtext, "Number of DUP Pseudocommands: %5d", count_dup_instruction);
317 sprintf(logtext, "Number of Mem Pseudocommands: %5d", count_pcmd_mem);
319 sprintf(logtext, "Number of Method Pseudocommands: %5d", count_pcmd_met);
321 sprintf(logtext, "Number of Branch Pseudocommands: %5d (rets:%5d, Xrets: %5d)",
322 count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
324 sprintf(logtext, "Number of Table Pseudocommands: %5d", count_pcmd_table);
326 sprintf(logtext, "Number of Useful Pseudocommands: %5d", count_pcmd_table +
327 count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
329 sprintf(logtext, "Number of Null Pointer Checks: %5d", count_check_null);
331 sprintf(logtext, "Number of Array Bound Checks: %5d", count_check_bound);
333 sprintf(logtext, "Number of Try-Blocks: %d", count_tryblocks);
335 sprintf(logtext, "Maximal count of stack elements: %d", count_max_new_stack);
337 sprintf(logtext, "Upper bound of max stack elements: %d", count_upper_bound_new_stack);
339 sprintf(logtext, "Distribution of stack sizes at block boundary");
341 sprintf(logtext, " 0 1 2 3 4 5 6 7 8 9 >=10");
343 sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_block_stack[0],
344 count_block_stack[1], count_block_stack[2], count_block_stack[3], count_block_stack[4],
345 count_block_stack[5], count_block_stack[6], count_block_stack[7], count_block_stack[8],
346 count_block_stack[9], count_block_stack[10]);
348 sprintf(logtext, "Distribution of store stack depth");
350 sprintf(logtext, " 0 1 2 3 4 5 6 7 8 9 >=10");
352 sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_depth[0],
353 count_store_depth[1], count_store_depth[2], count_store_depth[3], count_store_depth[4],
354 count_store_depth[5], count_store_depth[6], count_store_depth[7], count_store_depth[8],
355 count_store_depth[9], count_store_depth[10]);
357 sprintf(logtext, "Distribution of store creator chains first part");
359 sprintf(logtext, " 0 1 2 3 4 5 6 7 8 9 ");
361 sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[0],
362 count_store_length[1], count_store_length[2], count_store_length[3], count_store_length[4],
363 count_store_length[5], count_store_length[6], count_store_length[7], count_store_length[8],
364 count_store_length[9]);
366 sprintf(logtext, "Distribution of store creator chains second part");
368 sprintf(logtext, " 10 11 12 13 14 15 16 17 18 19 >=20");
370 sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[10],
371 count_store_length[11], count_store_length[12], count_store_length[13], count_store_length[14],
372 count_store_length[15], count_store_length[16], count_store_length[17], count_store_length[18],
373 count_store_length[19], count_store_length[20]);
375 sprintf(logtext, "Distribution of analysis iterations");
377 sprintf(logtext, " 1 2 3 4 >=5");
379 sprintf(logtext, "%5d%5d%5d%5d%5d", count_analyse_iterations[0], count_analyse_iterations[1],
380 count_analyse_iterations[2], count_analyse_iterations[3], count_analyse_iterations[4]);
382 sprintf(logtext, "Distribution of basic blocks per method");
384 sprintf(logtext, " <= 5 <=10 <=15 <=20 <=30 <=40 <=50 <=75 >75");
386 sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_method_bb_distribution[0],
387 count_method_bb_distribution[1], count_method_bb_distribution[2], count_method_bb_distribution[3],
388 count_method_bb_distribution[4], count_method_bb_distribution[5], count_method_bb_distribution[6],
389 count_method_bb_distribution[7], count_method_bb_distribution[8]);
391 sprintf(logtext, "Distribution of basic block sizes");
394 " 0 1 2 3 4 5 6 7 8 9 <13 <15 <17 <19 <21 <26 <31 >30");
396 sprintf(logtext, "%3d%5d%5d%5d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d",
397 count_block_size_distribution[0], count_block_size_distribution[1], count_block_size_distribution[2],
398 count_block_size_distribution[3], count_block_size_distribution[4], count_block_size_distribution[5],
399 count_block_size_distribution[6], count_block_size_distribution[7], count_block_size_distribution[8],
400 count_block_size_distribution[9], count_block_size_distribution[10], count_block_size_distribution[11],
401 count_block_size_distribution[12], count_block_size_distribution[13], count_block_size_distribution[14],
402 count_block_size_distribution[15], count_block_size_distribution[16], count_block_size_distribution[17]);
404 sprintf(logtext, "Size of Code Area (Kb): %10.3f", (float) count_code_len / 1024);
406 sprintf(logtext, "Size of data Area (Kb): %10.3f", (float) count_data_len / 1024);
408 sprintf(logtext, "Size of Class Infos (Kb):%10.3f", (float) (count_class_infos) / 1024);
410 sprintf(logtext, "Size of Const Pool (Kb): %10.3f", (float) (count_const_pool_len + count_utf_len) / 1024);
412 sprintf(logtext, "Size of Vftbl (Kb): %10.3f", (float) count_vftbl_len / 1024);
414 sprintf(logtext, "Size of comp stub (Kb): %10.3f", (float) count_cstub_len / 1024);
416 sprintf(logtext, "Size of native stub (Kb):%10.3f", (float) count_nstub_len / 1024);
418 sprintf(logtext, "Size of Utf (Kb): %10.3f", (float) count_utf_len / 1024);
420 sprintf(logtext, "Size of VMCode (Kb): %10.3f(%d)", (float) count_vmcode_len / 1024,
421 count_vmcode_len - 18 * count_all_methods);
423 sprintf(logtext, "Size of ExTable (Kb): %10.3f", (float) count_extable_len / 1024);
425 sprintf(logtext, "Number of class loads: %d", count_class_loads);
427 sprintf(logtext, "Number of class inits: %d", count_class_inits);
429 sprintf(logtext, "Number of loaded Methods: %d\n\n", count_all_methods);
432 sprintf(logtext, "Calls of utf_new: %22d", count_utf_new);
434 sprintf(logtext, "Calls of utf_new (element found): %6d\n\n", count_utf_new_found);
440 /********** Function: class_compile_methods (debugging only) ********/
442 void class_compile_methods ()
448 c = list_first (&linkedclasses);
450 for (i = 0; i < c -> methodscount; i++) {
451 m = &(c->methods[i]);
453 (void) jit_compile(m);
456 c = list_next (&linkedclasses, c);
463 * void exit_handler(void)
464 * -----------------------
465 * The exit_handler function is called upon program termination to shutdown
466 * the various subsystems and release the resources allocated to the VM.
468 void exit_handler(void)
470 /********************* Print debug tables ************************/
472 if (showmethods) class_showmethods (topclass);
473 if (showconstantpool) class_showconstantpool (topclass);
474 if (showutf) utf_show ();
477 clear_thread_flags(); /* restores standard file descriptor
481 /************************ Free all resources *******************/
483 heap_close (); /* must be called before compiler_close and
484 loader_close because finalization occurs
488 tables_close ( literalstring_free );
490 if (verbose || getcompilingtime || statistics) {
491 log_text ("CACAO terminated");
494 if (getcompilingtime)
502 /************************** Function: main *******************************
506 **************************************************************************/
508 int main(int argc, char **argv)
512 java_objectheader *local_exceptionptr = 0;
515 /********** interne (nur fuer main relevante Optionen) **************/
517 char logfilename[200] = "";
518 u4 heapsize = 64000000;
519 u4 heapstartsize = 200000;
520 char classpath[500] = ".:/usr/local/lib/java/classes";
522 char *specificmethodname = NULL;
523 char *specificsignature = NULL;
526 stackbottom = &dummy;
529 if (0 != atexit(exit_handler))
530 panic("unable to register exit_handler");
532 /************ Collect info from the environment ************************/
534 cp = getenv("CLASSPATH");
536 strcpy(classpath, cp);
539 /***************** Interpret the command line *****************/
544 while ((i = get_opt(argc,argv)) != OPT_DONE) {
546 case OPT_IGNORE: break;
549 strcpy (classpath + strlen(classpath), ":");
550 strcpy (classpath + strlen(classpath), opt_arg);
556 int l = strlen(opt_arg);
557 for (n = 0; n < l; n++) {
558 if (opt_arg[n]=='=') {
560 attach_property(opt_arg, opt_arg + n + 1);
573 if (opt_arg[strlen(opt_arg) - 1] == 'k') {
574 j = 1024 * atoi(opt_arg);
576 else if (opt_arg[strlen(opt_arg) - 1] == 'm') {
577 j = 1024 * 1024 * atoi(opt_arg);
579 else j = atoi(opt_arg);
581 if (i == OPT_MX) heapsize = j;
582 else heapstartsize = j;
593 compileverbose = true;
597 collectverbose = true;
600 case OPT_VERBOSECALL:
613 getcompilingtime = true;
614 getloadingtime = true;
622 strcpy(logfilename, opt_arg);
626 for (j = 0; j < strlen(opt_arg); j++) {
627 switch (opt_arg[j]) {
643 makeinitializations = false;
648 specificmethodname = opt_arg;
649 makeinitializations = false;
653 specificsignature = opt_arg;
659 makeinitializations = false;
662 case OPT_SHOW: /* Display options */
663 for (j = 0; j < strlen(opt_arg); j++) {
664 switch (opt_arg[j]) {
666 showdisassemble = true;
670 showconstantpool = true;
673 showddatasegment = true;
676 showintermediate = true;
677 compileverbose = true;
697 for (j = 0; j < strlen(opt_arg); j++) {
698 switch (opt_arg[j]) {
703 inlinevirtuals = true;
706 inlineexceptions = true;
709 inlineparamopt = true;
712 inlineoutsiders = true;
726 /***opt_xta = true; not yet **/
730 /***opt_vta = true; not yet **/
740 if (opt_ind >= argc) {
746 /**************************** Program start *****************************/
748 log_init(logfilename);
750 log_text("CACAO started -------------------------------------------------------");
753 suck_init(classpath);
754 native_setclasspath(classpath);
757 heap_init(heapsize, heapstartsize, &dummy);
761 native_loadclasses();
764 /*********************** Load JAVA classes ***************************/
766 cp = argv[opt_ind++];
767 for (i = strlen(cp) - 1; i >= 0; i--) { /* Transform dots into slashes */
768 if (cp[i] == '.') cp[i] = '/'; /* in the class name */
771 topclass = loader_load( utf_new_char (cp) );
773 if (exceptionptr != 0) {
774 printf("#### Class loader has thrown: ");
775 utf_display(exceptionptr->vftbl->class->name);
782 printf("#### Could not find top class - exiting\n");
789 initThreads((u1*) &dummy); /* schani */
792 /************************* Start worker routines ********************/
795 methodinfo *mainmethod;
798 heap_addreference((void**) &a);
800 mainmethod = class_findmethod (
802 utf_new_char ("main"),
803 utf_new_char ("([Ljava/lang/String;)V")
805 if (!mainmethod) panic("Can not find method 'void main(String[])'");
806 if ((mainmethod->flags & ACC_STATIC) != ACC_STATIC) panic("main is not static!");
808 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
809 for (i = opt_ind; i < argc; i++) {
810 a->data[i - opt_ind] = javastring_new(utf_new_char(argv[i]));
812 local_exceptionptr = asm_calljavamethod(mainmethod, a, NULL, NULL, NULL);
814 if (local_exceptionptr) {
815 printf("#### Program has thrown: ");
816 utf_display(local_exceptionptr->vftbl->class->name);
819 /*RTAprint*/ if ((pCallgraph >= 1) && (opt_rt)) {
820 /*RTAprint*/ printCallgraph (); }
822 /*RTprint*/ if ((pClassHeir >= 1) && (opt_rt)) {
823 /*RTprint*/ printf("Last RTA Info -");
824 /*RTprint*/ printRThierarchyInfo(mainmethod);
826 /*RTprint*/ printObjectClassHeirarchy1( );
830 killThread(currentThread);
832 fprintf(stderr, "still here\n");
835 /************* If requested, compile all methods ********************/
838 class_compile_methods();
842 /******** If requested, compile a specific method ***************/
844 if (specificmethodname) {
846 if (specificsignature)
847 m = class_findmethod(topclass,
848 utf_new_char(specificmethodname),
849 utf_new_char(specificsignature));
851 m = class_findmethod(topclass,
852 utf_new_char(specificmethodname), NULL);
853 if (!m) panic ("Specific method not found");
854 (void) jit_compile(m);
862 /************************************ Shutdown function *********************************
864 Terminates the system immediately without freeing memory explicitly (to be
865 used only for abnormal termination)
867 *****************************************************************************************/
869 void cacao_shutdown(s4 status)
871 if ((pCallgraph >= 1) && (opt_rt)) {
872 printCallgraph(NULL);
875 if ((pClassHeir >= 1) && (opt_rt)) {
876 printf("RTA Information -");
877 printRThierarchyInfo(NULL);
880 if (verbose || getcompilingtime || statistics) {
881 log_text ("CACAO terminated by shutdown");
884 if (getcompilingtime)
887 sprintf(logtext, "Exit status: %d\n", (int) status);
896 * These are local overrides for various environment variables in Emacs.
897 * Please do not remove this and leave it at the end of the file, where
898 * Emacs will automagically detect them.
899 * ---------------------------------------------------------------------
902 * indent-tabs-mode: t