1 /* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
2 /******************************* main.c ****************************************
4 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
6 See file COPYRIGHT for information on usage and disclaimer of warranties
8 Enthaelt die Funktion main() und die Variablen fuer die
10 Dieser Modul erledigt folgende Aufgaben:
11 - Bearbeiten der command-line-options
12 - Aufrufen aller Initialisierungsroutinen
13 - Aufrufen des Classloaders
14 - Starten der main - Methode
16 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
17 Changes: Andi Krall EMAIL: cacao@complang.tuwien.ac.at
18 Mark Probst EMAIL: cacao@complang.tuwien.ac.at
20 Last Change: 1997/10/29
22 *******************************************************************************/
28 #include "ncomp/ncomp.h"
35 #include "threads/thread.h" /* schani */
37 bool compileall = false;
38 int newcompiler = true;
42 void **stackbottom = 0;
46 /********************* interne Funktion: get_opt *****************************
48 liest die n"achste Option aus der Kommandozeile
50 ******************************************************************************/
56 #define OPT_CLASSPATH 2
60 #define OPT_VERBOSE1 6
62 #define OPT_VERBOSEGC 8
63 #define OPT_VERBOSECALL 9
65 #define OPT_SOFTNULL 11
72 #define OPT_SIGNATURE 18
77 struct { char *name; bool arg; int value; } opts[] = {
78 { "classpath", true, OPT_CLASSPATH },
80 { "ms", true, OPT_MS },
81 { "mx", true, OPT_MX },
82 { "noasyncgc", false, OPT_IGNORE },
83 { "noverify", false, OPT_IGNORE },
84 { "oss", true, OPT_IGNORE },
85 { "ss", true, OPT_IGNORE },
86 { "v", false, OPT_VERBOSE1 },
87 { "verbose", false, OPT_VERBOSE },
88 { "verbosegc", false, OPT_VERBOSEGC },
89 { "verbosecall", false, OPT_VERBOSECALL },
90 { "ieee", false, OPT_IEEE },
91 { "softnull", false, OPT_SOFTNULL },
92 { "time", false, OPT_TIME },
93 { "stat", false, OPT_STAT },
94 { "log", true, OPT_LOG },
95 { "c", true, OPT_CHECK },
96 { "l", false, OPT_LOAD },
97 { "m", true, OPT_METHOD },
98 { "sig", true, OPT_SIGNATURE },
99 { "s", true, OPT_SHOW },
100 { "all", false, OPT_ALL },
101 { "old", false, OPT_OLD },
105 static int opt_ind = 1;
106 static char *opt_arg;
108 static int get_opt (int argc, char **argv)
113 if (opt_ind >= argc) return OPT_DONE;
116 if (a[0] != '-') return OPT_DONE;
118 for (i=0; opts[i].name; i++) {
120 if (strcmp(a+1, opts[i].name) == 0) { /* boolean option found */
122 return opts[i].value;
126 if (strcmp(a+1, opts[i].name) == 0) { /* parameter option found */
128 if (opt_ind < argc) {
129 opt_arg = argv[opt_ind];
131 return opts[i].value;
136 size_t l = strlen(opts[i].name);
137 if (strlen(a+1) > l) {
138 if (memcmp (a+1, opts[i].name, l)==0) {
141 return opts[i].value;
154 /******************** interne Funktion: print_usage ************************
156 Gibt die richtige Aufrufsyntax des JavaVM-Compilers auf stdout aus.
158 ***************************************************************************/
160 static void print_usage()
162 printf ("USAGE: cacao [options] classname [program arguments\n");
163 printf ("Options:\n");
164 printf (" -classpath path ...... specify a path to look for classes\n");
165 printf (" -Dpropertyname=value . add an entry to the property list\n");
166 printf (" -mx maxmem[k|m] ...... specify the size for the heap\n");
167 printf (" -ms initmem[k|m] ..... specify the initial size for the heap\n");
168 printf (" -v ................... write state-information\n");
169 printf (" -verbose ............. write more information\n");
170 printf (" -verbosegc ........... write message for each GC\n");
171 printf (" -verbosecall ......... write message for each call\n");
172 printf (" -ieee ................ use ieee compliant arithmetic\n");
173 printf (" -softnull ............ use software nullpointer check\n");
174 printf (" -time ................ measure the runtime\n");
175 printf (" -stat ................ detailed compiler statistics\n");
176 printf (" -log logfile ......... specify a name for the logfile\n");
177 printf (" -c(heck) b(ounds...... don't check array bounds\n");
178 printf (" s(ync) ...... don't check for synchronization\n");
179 printf (" -l ................... don't start the class after loading\n");
180 printf (" -all ................. compile all methods, no execution\n");
181 printf (" -old ................. use old JIT compiler\n");
182 printf (" -m ................... compile only a specific method\n");
183 printf (" -sig ................. specify signature for a specific method\n");
184 printf (" -s(how)m(ethods) ..... show all methods&fields of a class\n");
185 printf (" c(onstants) ... show the constant pool\n");
186 printf (" a(ssembler) ... show disassembled listing\n");
187 printf (" d(atasegment).. show data segment listing\n");
188 printf (" s(tack) ....... show stack for every javaVM-command\n");
189 printf (" i(ntermediate). show intermediate representation\n");
190 printf (" u(nicode) ..... show the unicode - hash\n");
195 /***************************** Funktion: print_times *********************
197 gibt eine Aufstellung der verwendeten CPU-Zeit aus
199 **************************************************************************/
201 static void print_times()
203 long int totaltime = getcputime();
204 long int runtime = totaltime - loadingtime - compilingtime;
206 sprintf (logtext, "Time for loading classes: %ld secs, %ld millis",
207 loadingtime / 1000000, (loadingtime % 1000000) / 1000);
209 sprintf (logtext, "Time for compiling code: %ld secs, %ld millis",
210 compilingtime / 1000000, (compilingtime % 1000000) / 1000);
212 sprintf (logtext, "Time for running program: %ld secs, %ld millis",
213 runtime / 1000000, (runtime % 1000000) / 1000);
215 sprintf (logtext, "Total time: %ld secs, %ld millis",
216 totaltime / 1000000, (totaltime % 1000000) / 1000);
225 /***************************** Funktion: print_stats *********************
227 outputs detailed compiler statistics
229 **************************************************************************/
231 static void print_stats()
233 sprintf (logtext, "Number of JitCompiler Calls: %d", count_jit_calls);
235 sprintf (logtext, "Number of compiled Methods: %d", count_methods);
237 sprintf (logtext, "Number of max basic blocks per method: %d", count_max_basic_blocks);
239 sprintf (logtext, "Number of compiled basic blocks: %d", count_basic_blocks);
241 sprintf (logtext, "Number of max JavaVM-Instructions per method: %d", count_max_javainstr);
243 sprintf (logtext, "Number of compiled JavaVM-Instructions: %d", count_javainstr);
245 sprintf (logtext, "Size of compiled JavaVM-Instructions: %d(%d)", count_javacodesize,
246 count_javacodesize - count_methods * 18);
248 sprintf (logtext, "Size of compiled Exception Tables: %d", count_javaexcsize);
250 sprintf (logtext, "Value of extended instruction set var: %d", has_ext_instr_set);
252 sprintf (logtext, "Number of Alpha-Instructions: %d", count_code_len >> 2);
254 sprintf (logtext, "Number of Spills: %d", count_spills);
256 sprintf (logtext, "Number of Activ Pseudocommands: %5d", count_pcmd_activ);
258 sprintf (logtext, "Number of Drop Pseudocommands: %5d", count_pcmd_drop);
260 sprintf (logtext, "Number of Const Pseudocommands: %5d (zero:%5d)", count_pcmd_load, count_pcmd_zero);
262 sprintf (logtext, "Number of ConstAlu Pseudocommands: %5d (cmp: %5d, store:%5d)", count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
264 sprintf (logtext, "Number of Move Pseudocommands: %5d", count_pcmd_move);
266 sprintf (logtext, "Number of Load Pseudocommands: %5d", count_load_instruction);
268 sprintf (logtext, "Number of Store Pseudocommands: %5d (combined: %5d)", count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
270 sprintf (logtext, "Number of OP Pseudocommands: %5d", count_pcmd_op);
272 sprintf (logtext, "Number of DUP Pseudocommands: %5d", count_dup_instruction);
274 sprintf (logtext, "Number of Mem Pseudocommands: %5d", count_pcmd_mem);
276 sprintf (logtext, "Number of Method Pseudocommands: %5d", count_pcmd_met);
278 sprintf (logtext, "Number of Branch Pseudocommands: %5d (rets:%5d, Xrets: %5d)",
279 count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
281 sprintf (logtext, "Number of Table Pseudocommands: %5d", count_pcmd_table);
283 sprintf (logtext, "Number of Useful Pseudocommands: %5d", count_pcmd_table +
284 count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
286 sprintf (logtext, "Number of Null Pointer Checks: %5d", count_check_null);
288 sprintf (logtext, "Number of Array Bound Checks: %5d", count_check_bound);
290 sprintf (logtext, "Number of Try-Blocks: %d", count_tryblocks);
292 sprintf (logtext, "Maximal count of stack elements: %d", count_max_new_stack);
294 sprintf (logtext, "Upper bound of max stack elements: %d", count_upper_bound_new_stack);
296 sprintf (logtext, "Distribution of stack sizes at block boundary");
298 sprintf (logtext, " 0 1 2 3 4 5 6 7 8 9 >=10");
300 sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_block_stack[0],
301 count_block_stack[1],count_block_stack[2],count_block_stack[3],count_block_stack[4],
302 count_block_stack[5],count_block_stack[6],count_block_stack[7],count_block_stack[8],
303 count_block_stack[9],count_block_stack[10]);
305 sprintf (logtext, "Distribution of store stack depth");
307 sprintf (logtext, " 0 1 2 3 4 5 6 7 8 9 >=10");
309 sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_depth[0],
310 count_store_depth[1],count_store_depth[2],count_store_depth[3],count_store_depth[4],
311 count_store_depth[5],count_store_depth[6],count_store_depth[7],count_store_depth[8],
312 count_store_depth[9],count_store_depth[10]);
314 sprintf (logtext, "Distribution of store creator chains first part");
316 sprintf (logtext, " 0 1 2 3 4 5 6 7 8 9 ");
318 sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[0],
319 count_store_length[1],count_store_length[2],count_store_length[3],count_store_length[4],
320 count_store_length[5],count_store_length[6],count_store_length[7],count_store_length[8],
321 count_store_length[9]);
323 sprintf (logtext, "Distribution of store creator chains second part");
325 sprintf (logtext, " 10 11 12 13 14 15 16 17 18 19 >=20");
327 sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[10],
328 count_store_length[11],count_store_length[12],count_store_length[13],count_store_length[14],
329 count_store_length[15],count_store_length[16],count_store_length[17],count_store_length[18],
330 count_store_length[19],count_store_length[20]);
332 sprintf (logtext, "Distribution of analysis iterations");
334 sprintf (logtext, " 1 2 3 4 >=5");
336 sprintf (logtext, "%5d%5d%5d%5d%5d", count_analyse_iterations[0],count_analyse_iterations[1],
337 count_analyse_iterations[2],count_analyse_iterations[3],count_analyse_iterations[4]);
339 sprintf (logtext, "Distribution of basic blocks per method");
341 sprintf (logtext, " <= 5 <=10 <=15 <=20 <=30 <=40 <=50 <=75 >75");
343 sprintf (logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_method_bb_distribution[0],
344 count_method_bb_distribution[1],count_method_bb_distribution[2],count_method_bb_distribution[3],
345 count_method_bb_distribution[4],count_method_bb_distribution[5],count_method_bb_distribution[6],
346 count_method_bb_distribution[7],count_method_bb_distribution[8]);
348 sprintf (logtext, "Distribution of basic block sizes");
351 " 1 2 3 4 5 6 7 8 9 10 <13 <15 <17 <19 <21 <26 <31 >30");
353 sprintf (logtext, "%3d%5d%5d%5d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d",
354 count_block_size_distribution[0], count_block_size_distribution[1], count_block_size_distribution[2],
355 count_block_size_distribution[3], count_block_size_distribution[4], count_block_size_distribution[5],
356 count_block_size_distribution[6], count_block_size_distribution[7], count_block_size_distribution[8],
357 count_block_size_distribution[9], count_block_size_distribution[10],count_block_size_distribution[11],
358 count_block_size_distribution[12],count_block_size_distribution[13],count_block_size_distribution[14],
359 count_block_size_distribution[15],count_block_size_distribution[16],count_block_size_distribution[17]);
361 sprintf (logtext, "Size of Code Area (Kb): %10.3f", (float) count_code_len / 1024);
363 sprintf (logtext, "Size of data Area (Kb): %10.3f", (float) count_data_len / 1024);
365 sprintf (logtext, "Size of Class Infos (Kb):%10.3f", (float) (count_class_infos) / 1024);
367 sprintf (logtext, "Size of Const Pool (Kb): %10.3f", (float) (count_const_pool_len + count_unicode_len) / 1024);
369 sprintf (logtext, "Size of Vftbl (Kb): %10.3f", (float) count_vftbl_len / 1024);
371 sprintf (logtext, "Size of comp stub (Kb): %10.3f", (float) count_cstub_len / 1024);
373 sprintf (logtext, "Size of native stub (Kb):%10.3f", (float) count_nstub_len / 1024);
375 sprintf (logtext, "Size of Unicode (Kb): %10.3f", (float) count_unicode_len / 1024);
377 sprintf (logtext, "Size of VMCode (Kb): %10.3f(%d)", (float) count_vmcode_len / 1024,
378 count_vmcode_len - 18 * count_all_methods);
380 sprintf (logtext, "Size of ExTable (Kb): %10.3f", (float) count_extable_len / 1024);
382 sprintf (logtext, "Number of loaded Methods: %d\n\n", count_all_methods);
387 /********** Funktion: class_compile_methods (nur f"ur Debug-Zwecke) ********/
389 void class_compile_methods ()
395 c = list_first (&linkedclasses);
397 for (i = 0; i < c -> methodscount; i++) {
398 m = &(c->methods[i]);
401 (void) new_compile(m);
403 (void) compiler_compile(m);
406 c = list_next (&linkedclasses, c);
411 /************************** Funktion: main *******************************
414 Wird vom System zu Programstart aufgerufen (eh klar).
416 **************************************************************************/
419 int main(int argc, char **argv)
424 java_objectheader *exceptionptr;
427 /********** interne (nur fuer main relevante Optionen) **************/
429 char logfilename[200] = "";
430 u4 heapsize = 16000000;
431 u4 heapstartsize = 200000;
432 char classpath[500] = ".:/usr/local/lib/java/classes";
433 bool showmethods = false;
434 bool showconstantpool = false;
435 bool showunicode = false;
437 char *specificmethodname = NULL;
438 char *specificsignature = NULL;
441 stackbottom = &dummy;
446 atexit(clear_thread_flags);
449 /************ Infos aus der Environment lesen ************************/
451 cp = getenv ("CLASSPATH");
453 strcpy (classpath, cp);
456 /***************** Interpretieren der Kommandozeile *****************/
461 while ( (i = get_opt(argc,argv)) != OPT_DONE) {
464 case OPT_IGNORE: break;
467 strcpy (classpath + strlen(classpath), ":");
468 strcpy (classpath + strlen(classpath), opt_arg);
473 int n,l=strlen(opt_arg);
474 for (n=0; n<l; n++) {
475 if (opt_arg[n]=='=') {
477 attach_property (opt_arg, opt_arg+n+1);
490 if (opt_arg[strlen(opt_arg)-1] == 'k') {
491 j = 1024 * atoi(opt_arg);
493 else if (opt_arg[strlen(opt_arg)-1] == 'm') {
494 j = 1024 * 1024 * atoi(opt_arg);
496 else j = atoi(opt_arg);
498 if (i==OPT_MX) heapsize = j;
499 else heapstartsize = j;
510 compileverbose = true;
514 collectverbose = true;
517 case OPT_VERBOSECALL:
530 getcompilingtime = true;
531 getloadingtime = true;
539 strcpy (logfilename, opt_arg);
544 for (j=0; j<strlen(opt_arg); j++) {
545 switch (opt_arg[j]) {
546 case 'b': checkbounds=false; break;
547 case 's': checksync=false; break;
548 default: print_usage();
556 makeinitializations = false;
561 specificmethodname = opt_arg;
562 makeinitializations = false;
566 specificsignature = opt_arg;
572 makeinitializations = false;
580 case OPT_SHOW: /* Anzeigeoptionen */
581 for (j=0; j<strlen(opt_arg); j++) {
582 switch (opt_arg[j]) {
583 case 'm': showmethods=true; break;
584 case 'c': showconstantpool=true; break;
585 case 'a': showdisassemble=true; compileverbose=true; break;
586 case 's': showstack=true; compileverbose=true; break;
587 case 'i': showintermediate=true; compileverbose=true; break;
588 case 'u': showunicode=true; break;
589 default: print_usage();
604 if (opt_ind >= argc) {
610 /**************************** Programmstart *****************************/
612 log_init (logfilename);
615 "CACAO started -------------------------------------------------------");
618 suck_init (classpath);
619 native_setclasspath (classpath);
622 heap_init(heapsize, heapstartsize, &dummy);
627 native_loadclasses ();
630 /*********************** JAVA-Klassen laden ***************************/
632 cp = argv[opt_ind++];
633 for (i=strlen(cp)-1; i>=0; i--) { /* Punkte im Klassennamen */
634 if (cp[i]=='.') cp[i]='/'; /* auf slashes umbauen */
637 topclass = loader_load ( unicode_new_char (cp) );
639 loader_compute_subclasses();
644 initThreads((u1*)&dummy); /* schani */
647 /************************* Arbeitsroutinen starten ********************/
650 methodinfo *mainmethod;
653 heap_addreference((void**) &a);
655 mainmethod = class_findmethod (
657 unicode_new_char ("main"),
658 unicode_new_char ("([Ljava/lang/String;)V")
660 if (!mainmethod) panic ("Can not find method 'void main(String[])'");
661 if ((mainmethod->flags & ACC_STATIC) != ACC_STATIC) panic ("main is not static!");
663 a = builtin_anewarray (argc - opt_ind, class_java_lang_String);
664 for (i=opt_ind; i<argc; i++) {
665 a->data[i-opt_ind] = javastring_new (unicode_new_char (argv[i]) );
667 exceptionptr = asm_calljavamethod (mainmethod, a, NULL,NULL,NULL );
670 printf ("#### Program has thrown: ");
671 unicode_display (exceptionptr->vftbl->class->name);
675 /* killThread(currentThread); */
679 /************* Auf Wunsch alle Methode "ubersetzen ********************/
682 class_compile_methods();
686 /******** Auf Wunsch eine spezielle Methode "ubersetzen ***************/
688 if (specificmethodname) {
690 if (specificsignature)
691 m = class_findmethod(topclass,
692 unicode_new_char(specificmethodname),
693 unicode_new_char(specificsignature));
695 m = class_findmethod(topclass,
696 unicode_new_char(specificmethodname), NULL);
697 if (!m) panic ("Specific method not found");
699 (void) new_compile(m);
701 (void) compiler_compile(m);
704 /********************* Debug-Tabellen ausgeben ************************/
706 if (showmethods) class_showmethods (topclass);
707 if (showconstantpool) class_showconstantpool (topclass);
708 if (showunicode) unicode_show ();
712 /************************ Freigeben aller Resourcen *******************/
714 heap_close (); /* must be called before compiler_close and
715 loader_close because finalization occurs
719 unicode_close ( literalstring_free );
722 /* Endemeldung ausgeben und mit entsprechendem exit-Status terminieren */
724 if (verbose || getcompilingtime || statistics) {
725 log_text ("CACAO terminated");
728 if (getcompilingtime)
739 /************************************ SHUTDOWN-Funktion *********************************
741 Terminiert das System augenblicklich, ohne den Speicher
742 explizit freizugeben (eigentlich nur f"ur abnorme
743 Programmterminierung)
745 *****************************************************************************************/
747 void cacao_shutdown(s4 status)
749 if (verbose || getcompilingtime || statistics) {
750 log_text ("CACAO terminated by shutdown");
753 if (getcompilingtime)
756 sprintf (logtext, "Exit status: %d\n", (int) status);