1 /* main.c **********************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Contains main() and variables for the global options.
8 This module does the following tasks:
9 - Command line option handling
10 - Calling initialization routines
11 - Calling the class loader
12 - Running the main method
14 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
15 Changes: Andi Krall EMAIL: cacao@complang.tuwien.ac.at
16 Mark Probst EMAIL: cacao@complang.tuwien.ac.at
17 Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at
19 Last Change: $Id: main.c 475 2003-10-04 18:59:36Z stefan $
21 *******************************************************************************/
36 #include "threads/thread.h"
38 bool compileall = false;
39 int newcompiler = true;
45 static bool showmethods = false;
46 static bool showconstantpool = false;
47 static bool showutf = false;
48 static classinfo *topclass;
51 void **stackbottom = 0;
55 /* internal function: get_opt *************************************************
57 decodes the next command line option
59 ******************************************************************************/
65 #define OPT_CLASSPATH 2
69 #define OPT_VERBOSE1 6
71 #define OPT_VERBOSEGC 8
72 #define OPT_VERBOSECALL 9
74 #define OPT_SOFTNULL 11
81 #define OPT_SIGNATURE 18
92 #define OPT_INLINING 25
98 struct {char *name; bool arg; int value;} opts[] = {
99 {"classpath", true, OPT_CLASSPATH},
101 {"ms", true, OPT_MS},
102 {"mx", true, OPT_MX},
103 {"noasyncgc", false, OPT_IGNORE},
104 {"noverify", false, OPT_IGNORE},
105 {"oss", true, OPT_IGNORE},
106 {"ss", true, OPT_IGNORE},
107 {"v", false, OPT_VERBOSE1},
108 {"verbose", false, OPT_VERBOSE},
109 {"verbosegc", false, OPT_VERBOSEGC},
110 {"verbosecall", false, OPT_VERBOSECALL},
111 {"ieee", false, OPT_IEEE},
112 {"softnull", false, OPT_SOFTNULL},
113 {"time", false, OPT_TIME},
114 {"stat", false, OPT_STAT},
115 {"log", true, OPT_LOG},
116 {"c", true, OPT_CHECK},
117 {"l", false, OPT_LOAD},
118 {"m", true, OPT_METHOD},
119 {"sig", true, OPT_SIGNATURE},
120 {"s", true, OPT_SHOW},
121 {"all", false, OPT_ALL},
123 {"old", false, OPT_OLD},
126 {"gc1", false, OPT_GC1},
127 {"gc2", false, OPT_GC2},
129 {"oloop", false, OPT_OLOOP},
130 {"i", true, OPT_INLINING},
131 {"rt", false, OPT_RT},
132 {"xta", false, OPT_XTA},
133 {"vta", false, OPT_VTA},
137 static int opt_ind = 1;
138 static char *opt_arg;
140 static int get_opt (int argc, char **argv)
145 if (opt_ind >= argc) return OPT_DONE;
148 if (a[0] != '-') return OPT_DONE;
150 for (i=0; opts[i].name; i++) {
152 if (strcmp(a+1, opts[i].name) == 0) { /* boolean option found */
154 return opts[i].value;
158 if (strcmp(a+1, opts[i].name) == 0) { /* parameter option found */
160 if (opt_ind < argc) {
161 opt_arg = argv[opt_ind];
163 return opts[i].value;
168 size_t l = strlen(opts[i].name);
169 if (strlen(a+1) > l) {
170 if (memcmp (a+1, opts[i].name, l)==0) {
173 return opts[i].value;
186 /******************** interne Function: print_usage ************************
188 Prints the correct usage syntax to stdout.
190 ***************************************************************************/
192 static void print_usage()
194 printf ("USAGE: cacao [options] classname [program arguments]\n");
195 printf ("Options:\n");
196 printf (" -classpath path ...... specify a path to look for classes\n");
197 printf (" -Dpropertyname=value . add an entry to the property list\n");
198 printf (" -mx maxmem[k|m] ...... specify the size for the heap\n");
199 printf (" -ms initmem[k|m] ..... specify the initial size for the heap\n");
200 printf (" -v ................... write state-information\n");
201 printf (" -verbose ............. write more information\n");
202 printf (" -verbosegc ........... write message for each GC\n");
203 printf (" -verbosecall ......... write message for each call\n");
204 printf (" -ieee ................ use ieee compliant arithmetic\n");
205 printf (" -softnull ............ use software nullpointer check\n");
206 printf (" -time ................ measure the runtime\n");
207 printf (" -stat ................ detailed compiler statistics\n");
208 printf (" -log logfile ......... specify a name for the logfile\n");
209 printf (" -c(heck)b(ounds) ..... don't check array bounds\n");
210 printf (" s(ync) ....... don't check for synchronization\n");
211 printf (" -oloop ............... optimize array accesses in loops\n");
212 printf (" -l ................... don't start the class after loading\n");
213 printf (" -all ................. compile all methods, no execution\n");
215 printf (" -old ................. use old JIT compiler\n");
218 printf (" -gc1 ................. use the old garbage collector (default)\n");
219 printf (" -gc2 ................. use the new garbage collector\n");
221 printf (" -m ................... compile only a specific method\n");
222 printf (" -sig ................. specify signature for a specific method\n");
223 printf (" -s(how)a(ssembler) ... show disassembled listing\n");
224 printf (" c(onstants) ... show the constant pool\n");
225 printf (" d(atasegment).. show data segment listing\n");
226 printf (" i(ntermediate). show intermediate representation\n");
227 printf (" m(ethods)...... show class fields and methods\n");
229 printf (" s(tack) ....... show stack for every javaVM-command\n");
231 printf (" u(tf) ......... show the utf - hash\n");
232 printf (" -i n ............. activate inlining\n");
233 printf (" v ............. inline virtual methods\n");
234 printf (" e ............. inline methods with exceptions\n");
235 printf (" p ............. optimize argument renaming\n");
236 printf (" o ............. inline methods of foreign classes\n");
237 printf (" -rt .................. use rapid type analysis\n");
238 printf (" -xta ................. use x type analysis\n");
239 printf (" -vta ................. use variable type analysis\n");
244 /***************************** Function: print_times *********************
246 Prints a summary of CPU time usage.
248 **************************************************************************/
250 static void print_times()
252 long int totaltime = getcputime();
253 long int runtime = totaltime - loadingtime - compilingtime;
255 sprintf (logtext, "Time for loading classes: %ld secs, %ld millis",
256 loadingtime / 1000000, (loadingtime % 1000000) / 1000);
258 sprintf (logtext, "Time for compiling code: %ld secs, %ld millis",
259 compilingtime / 1000000, (compilingtime % 1000000) / 1000);
261 sprintf (logtext, "Time for running program: %ld secs, %ld millis",
262 runtime / 1000000, (runtime % 1000000) / 1000);
264 sprintf (logtext, "Total time: %ld secs, %ld millis",
265 totaltime / 1000000, (totaltime % 1000000) / 1000);
274 /***************************** Function: print_stats *********************
276 outputs detailed compiler statistics
278 **************************************************************************/
280 static void print_stats()
282 sprintf (logtext, "Number of JitCompiler Calls: %d", count_jit_calls);
284 sprintf (logtext, "Number of compiled Methods: %d", count_methods);
286 sprintf (logtext, "Number of max basic blocks per method: %d", count_max_basic_blocks);
288 sprintf (logtext, "Number of compiled basic blocks: %d", count_basic_blocks);
290 sprintf (logtext, "Number of max JavaVM-Instructions per method: %d", count_max_javainstr);
292 sprintf (logtext, "Number of compiled JavaVM-Instructions: %d", count_javainstr);
294 sprintf (logtext, "Size of compiled JavaVM-Instructions: %d(%d)", count_javacodesize,
295 count_javacodesize - count_methods * 18);
297 sprintf (logtext, "Size of compiled Exception Tables: %d", count_javaexcsize);
299 sprintf (logtext, "Value of extended instruction set var: %d", has_ext_instr_set);
301 sprintf (logtext, "Number of Machine-Instructions: %d", count_code_len >> 2);
303 sprintf (logtext, "Number of Spills: %d", count_spills);
305 sprintf (logtext, "Number of Activ Pseudocommands: %5d", count_pcmd_activ);
307 sprintf (logtext, "Number of Drop Pseudocommands: %5d", count_pcmd_drop);
309 sprintf (logtext, "Number of Const Pseudocommands: %5d (zero:%5d)", count_pcmd_load, count_pcmd_zero);
311 sprintf (logtext, "Number of ConstAlu Pseudocommands: %5d (cmp: %5d, store:%5d)", count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
313 sprintf (logtext, "Number of Move Pseudocommands: %5d", count_pcmd_move);
315 sprintf (logtext, "Number of Load Pseudocommands: %5d", count_load_instruction);
317 sprintf (logtext, "Number of Store Pseudocommands: %5d (combined: %5d)", count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
319 sprintf (logtext, "Number of OP Pseudocommands: %5d", count_pcmd_op);
321 sprintf (logtext, "Number of DUP Pseudocommands: %5d", count_dup_instruction);
323 sprintf (logtext, "Number of Mem Pseudocommands: %5d", count_pcmd_mem);
325 sprintf (logtext, "Number of Method Pseudocommands: %5d", count_pcmd_met);
327 sprintf (logtext, "Number of Branch Pseudocommands: %5d (rets:%5d, Xrets: %5d)",
328 count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
330 sprintf (logtext, "Number of Table Pseudocommands: %5d", count_pcmd_table);
332 sprintf (logtext, "Number of Useful Pseudocommands: %5d", count_pcmd_table +
333 count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
335 sprintf (logtext, "Number of Null Pointer Checks: %5d", count_check_null);
337 sprintf (logtext, "Number of Array Bound Checks: %5d", count_check_bound);
339 sprintf (logtext, "Number of Try-Blocks: %d", count_tryblocks);
341 sprintf (logtext, "Maximal count of stack elements: %d", count_max_new_stack);
343 sprintf (logtext, "Upper bound of max stack elements: %d", count_upper_bound_new_stack);
345 sprintf (logtext, "Distribution of stack sizes at block boundary");
347 sprintf (logtext, " 0 1 2 3 4 5 6 7 8 9 >=10");
349 sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_block_stack[0],
350 count_block_stack[1],count_block_stack[2],count_block_stack[3],count_block_stack[4],
351 count_block_stack[5],count_block_stack[6],count_block_stack[7],count_block_stack[8],
352 count_block_stack[9],count_block_stack[10]);
354 sprintf (logtext, "Distribution of store stack depth");
356 sprintf (logtext, " 0 1 2 3 4 5 6 7 8 9 >=10");
358 sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_depth[0],
359 count_store_depth[1],count_store_depth[2],count_store_depth[3],count_store_depth[4],
360 count_store_depth[5],count_store_depth[6],count_store_depth[7],count_store_depth[8],
361 count_store_depth[9],count_store_depth[10]);
363 sprintf (logtext, "Distribution of store creator chains first part");
365 sprintf (logtext, " 0 1 2 3 4 5 6 7 8 9 ");
367 sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[0],
368 count_store_length[1],count_store_length[2],count_store_length[3],count_store_length[4],
369 count_store_length[5],count_store_length[6],count_store_length[7],count_store_length[8],
370 count_store_length[9]);
372 sprintf (logtext, "Distribution of store creator chains second part");
374 sprintf (logtext, " 10 11 12 13 14 15 16 17 18 19 >=20");
376 sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[10],
377 count_store_length[11],count_store_length[12],count_store_length[13],count_store_length[14],
378 count_store_length[15],count_store_length[16],count_store_length[17],count_store_length[18],
379 count_store_length[19],count_store_length[20]);
381 sprintf (logtext, "Distribution of analysis iterations");
383 sprintf (logtext, " 1 2 3 4 >=5");
385 sprintf (logtext, "%5d%5d%5d%5d%5d", count_analyse_iterations[0],count_analyse_iterations[1],
386 count_analyse_iterations[2],count_analyse_iterations[3],count_analyse_iterations[4]);
388 sprintf (logtext, "Distribution of basic blocks per method");
390 sprintf (logtext, " <= 5 <=10 <=15 <=20 <=30 <=40 <=50 <=75 >75");
392 sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_method_bb_distribution[0],
393 count_method_bb_distribution[1],count_method_bb_distribution[2],count_method_bb_distribution[3],
394 count_method_bb_distribution[4],count_method_bb_distribution[5],count_method_bb_distribution[6],
395 count_method_bb_distribution[7],count_method_bb_distribution[8]);
397 sprintf (logtext, "Distribution of basic block sizes");
400 " 0 1 2 3 4 5 6 7 8 9 <13 <15 <17 <19 <21 <26 <31 >30");
402 sprintf (logtext, "%3d%5d%5d%5d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d",
403 count_block_size_distribution[0], count_block_size_distribution[1], count_block_size_distribution[2],
404 count_block_size_distribution[3], count_block_size_distribution[4], count_block_size_distribution[5],
405 count_block_size_distribution[6], count_block_size_distribution[7], count_block_size_distribution[8],
406 count_block_size_distribution[9], count_block_size_distribution[10],count_block_size_distribution[11],
407 count_block_size_distribution[12],count_block_size_distribution[13],count_block_size_distribution[14],
408 count_block_size_distribution[15],count_block_size_distribution[16],count_block_size_distribution[17]);
410 sprintf (logtext, "Size of Code Area (Kb): %10.3f", (float) count_code_len / 1024);
412 sprintf (logtext, "Size of data Area (Kb): %10.3f", (float) count_data_len / 1024);
414 sprintf (logtext, "Size of Class Infos (Kb):%10.3f", (float) (count_class_infos) / 1024);
416 sprintf (logtext, "Size of Const Pool (Kb): %10.3f", (float) (count_const_pool_len + count_utf_len) / 1024);
418 sprintf (logtext, "Size of Vftbl (Kb): %10.3f", (float) count_vftbl_len / 1024);
420 sprintf (logtext, "Size of comp stub (Kb): %10.3f", (float) count_cstub_len / 1024);
422 sprintf (logtext, "Size of native stub (Kb):%10.3f", (float) count_nstub_len / 1024);
424 sprintf (logtext, "Size of Utf (Kb): %10.3f", (float) count_utf_len / 1024);
426 sprintf (logtext, "Size of VMCode (Kb): %10.3f(%d)", (float) count_vmcode_len / 1024,
427 count_vmcode_len - 18 * count_all_methods);
429 sprintf (logtext, "Size of ExTable (Kb): %10.3f", (float) count_extable_len / 1024);
431 sprintf (logtext, "Number of class loads: %d", count_class_loads);
433 sprintf (logtext, "Number of class inits: %d", count_class_inits);
435 sprintf (logtext, "Number of loaded Methods: %d\n\n", count_all_methods);
438 sprintf (logtext, "Calls of utf_new: %22d", count_utf_new);
440 sprintf (logtext, "Calls of utf_new (element found): %6d\n\n", count_utf_new_found);
445 /********** Function: class_compile_methods (debugging only) ********/
447 void class_compile_methods ()
453 c = list_first (&linkedclasses);
455 for (i = 0; i < c -> methodscount; i++) {
456 m = &(c->methods[i]);
461 (void) jit_compile(m);
464 (void) compiler_compile(m);
468 c = list_next (&linkedclasses, c);
473 * void exit_handler(void)
474 * -----------------------
475 * The exit_handler function is called upon program termination to shutdown
476 * the various subsystems and release the resources allocated to the VM.
479 void exit_handler(void)
481 /********************* Print debug tables ************************/
483 if (showmethods) class_showmethods (topclass);
484 if (showconstantpool) class_showconstantpool (topclass);
485 if (showutf) utf_show ();
488 clear_thread_flags(); /* restores standard file descriptor
492 /************************ Free all resources *******************/
494 heap_close (); /* must be called before compiler_close and
495 loader_close because finalization occurs
502 tables_close ( literalstring_free );
504 if (verbose || getcompilingtime || statistics) {
505 log_text ("CACAO terminated");
508 if (getcompilingtime)
514 /************************** Function: main *******************************
518 **************************************************************************/
520 int main(int argc, char **argv)
524 java_objectheader *local_exceptionptr = 0;
527 /********** interne (nur fuer main relevante Optionen) **************/
529 char logfilename[200] = "";
530 u4 heapsize = 64000000;
531 u4 heapstartsize = 200000;
532 char classpath[500] = ".:/usr/local/lib/java/classes";
534 char *specificmethodname = NULL;
535 char *specificsignature = NULL;
538 stackbottom = &dummy;
541 if (0 != atexit(exit_handler))
542 panic("unable to register exit_handler");
544 /************ Collect info from the environment ************************/
546 cp = getenv ("CLASSPATH");
548 strcpy (classpath, cp);
551 /***************** Interpret the command line *****************/
556 while ( (i = get_opt(argc,argv)) != OPT_DONE) {
559 case OPT_IGNORE: break;
562 strcpy (classpath + strlen(classpath), ":");
563 strcpy (classpath + strlen(classpath), opt_arg);
568 int n,l=strlen(opt_arg);
569 for (n=0; n<l; n++) {
570 if (opt_arg[n]=='=') {
572 attach_property (opt_arg, opt_arg+n+1);
585 if (opt_arg[strlen(opt_arg)-1] == 'k') {
586 j = 1024 * atoi(opt_arg);
588 else if (opt_arg[strlen(opt_arg)-1] == 'm') {
589 j = 1024 * 1024 * atoi(opt_arg);
591 else j = atoi(opt_arg);
593 if (i==OPT_MX) heapsize = j;
594 else heapstartsize = j;
605 compileverbose = true;
609 collectverbose = true;
612 case OPT_VERBOSECALL:
625 getcompilingtime = true;
626 getloadingtime = true;
634 strcpy (logfilename, opt_arg);
639 for (j=0; j<strlen(opt_arg); j++) {
640 switch (opt_arg[j]) {
641 case 'b': checkbounds=false; break;
642 case 's': checksync=false; break;
643 default: print_usage();
651 makeinitializations = false;
656 specificmethodname = opt_arg;
657 makeinitializations = false;
661 specificsignature = opt_arg;
667 makeinitializations = false;
687 case OPT_SHOW: /* Display options */
688 for (j=0; j<strlen(opt_arg); j++) {
689 switch (opt_arg[j]) {
690 case 'a': showdisassemble=true; compileverbose=true; break;
691 case 'c': showconstantpool=true; break;
692 case 'd': showddatasegment=true; break;
693 case 'i': showintermediate=true; compileverbose=true; break;
694 case 'm': showmethods=true; break;
696 case 's': showstack=true; compileverbose=true; break;
698 case 'u': showutf=true; break;
699 default: print_usage();
711 for (j=0; j<strlen(opt_arg); j++) {
712 switch (opt_arg[j]) {
713 case 'n': useinlining = true; break;
714 case 'v': inlinevirtuals = true; break;
715 case 'e': inlineexceptions = true; break;
716 case 'p': inlineparamopt = true; break;
717 case 'o': inlineoutsiders = true; break;
718 default: print_usage();
730 /***opt_xta = true; not yet **/
734 /***opt_vta = true; not yet **/
746 if (opt_ind >= argc) {
752 /**************************** Program start *****************************/
754 log_init (logfilename);
757 "CACAO started -------------------------------------------------------");
760 suck_init (classpath);
761 native_setclasspath (classpath);
764 heap_init(heapsize, heapstartsize, &dummy);
771 native_loadclasses ();
774 /*********************** Load JAVA classes ***************************/
776 cp = argv[opt_ind++];
777 for (i=strlen(cp)-1; i>=0; i--) { /* Transform dots into slashes */
778 if (cp[i]=='.') cp[i]='/'; /* in the class name */
781 topclass = loader_load ( utf_new_char (cp) );
783 if (exceptionptr != 0)
785 printf ("#### Class loader has thrown: ");
786 utf_display (exceptionptr->vftbl->class->name);
794 printf("#### Could not find top class - exiting\n");
801 initThreads((u1*)&dummy); /* schani */
804 /************************* Start worker routines ********************/
807 methodinfo *mainmethod;
810 heap_addreference((void**) &a);
812 mainmethod = class_findmethod (
814 utf_new_char ("main"),
815 utf_new_char ("([Ljava/lang/String;)V")
817 if (!mainmethod) panic ("Can not find method 'void main(String[])'");
818 if ((mainmethod->flags & ACC_STATIC) != ACC_STATIC) panic ("main is not static!");
820 a = builtin_anewarray (argc - opt_ind, class_java_lang_String);
821 for (i=opt_ind; i<argc; i++) {
822 a->data[i-opt_ind] = javastring_new (utf_new_char (argv[i]) );
824 local_exceptionptr = asm_calljavamethod (mainmethod, a, NULL,NULL,NULL );
826 if (local_exceptionptr) {
827 printf ("#### Program has thrown: ");
828 utf_display (local_exceptionptr->vftbl->class->name);
831 /*RTAprint*/ if ((pCallgraph >= 1) && (opt_rt)) {
832 /*RTAprint*/ printCallgraph (); }
834 /*RTprint*/ if ((pClassHeir >= 1) && (opt_rt)) {
835 /*RTprint*/ printf("Last RTA Info -");
836 /*RTprint*/ printRThierarchyInfo(mainmethod);
838 /*RTprint*/ printObjectClassHeirarchy1( );
842 killThread(currentThread);
844 fprintf(stderr, "still here\n");
847 /************* If requested, compile all methods ********************/
850 class_compile_methods();
854 /******** If requested, compile a specific method ***************/
856 if (specificmethodname) {
858 if (specificsignature)
859 m = class_findmethod(topclass,
860 utf_new_char(specificmethodname),
861 utf_new_char(specificsignature));
863 m = class_findmethod(topclass,
864 utf_new_char(specificmethodname), NULL);
865 if (!m) panic ("Specific method not found");
869 (void) jit_compile(m);
872 (void) compiler_compile(m);
881 /************************************ Shutdown function *********************************
883 Terminates the system immediately without freeing memory explicitly (to be
884 used only for abnormal termination)
886 *****************************************************************************************/
888 void cacao_shutdown(s4 status)
890 /*RTAprint*/ if ((pCallgraph >= 1) && (opt_rt)) {
891 /*RTAprint*/ printCallgraph (NULL); }
893 /*RTprint*/ if ((pClassHeir >= 1) && (opt_rt)) {
894 /*RTprint*/ printf("RTA Information -");
895 /*RTprint*/ printRThierarchyInfo(NULL); }
897 if (verbose || getcompilingtime || statistics) {
898 log_text ("CACAO terminated by shutdown");
901 if (getcompilingtime)
904 sprintf (logtext, "Exit status: %d\n", (int) status);
913 * These are local overrides for various environment variables in Emacs.
914 * Please do not remove this and leave it at the end of the file, where
915 * Emacs will automagically detect them.
916 * ---------------------------------------------------------------------
919 * indent-tabs-mode: t