asm_calljavafunction2 (untested)
[cacao.git] / main.c
1 /* main.c - contains main() and variables for the global options
2
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,
7    J. Wenninger
8
9    This file is part of CACAO.
10
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.
15
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.
20
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
24    02111-1307, USA.
25
26    Contact: cacao@complang.tuwien.ac.at
27
28    Authors: Reinhard Grafl
29
30    Changes: Andi Krall
31             Mark Probst
32             Philipp Tomsich
33
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
39
40    $Id: main.c 806 2003-12-21 13:56:27Z twisti $
41
42 */
43
44
45 #include <stdlib.h>
46 #include <string.h>
47 #include "main.h"
48 #include "global.h"
49 #include "tables.h"
50 #include "loader.h"
51 #include "jit.h"
52 #include "asmpart.h"
53 #include "builtin.h"
54 #include "native.h"
55 #include "mm/boehm.h"
56 #include "threads/thread.h"
57 #include "toolbox/loging.h"
58 #include "toolbox/memory.h"
59 #include "parseRTstats.h"
60 #include "typeinfo.h" /* XXX remove debug */
61 #include "nat/java_lang_Throwable.h"
62
63
64 /* command line option */
65
66 bool verbose =  false;
67 bool compileall = false;
68 bool runverbose = false;
69 bool collectverbose = false;
70
71 bool loadverbose = false;
72 bool linkverbose = false;
73 bool initverbose = false;
74
75 bool opt_rt = false;            /* true if RTA parse should be used     RT-CO */
76 bool opt_xta = false;           /* true if XTA parse should be used    XTA-CO */
77 bool opt_vta = false;           /* true if VTA parse should be used    VTA-CO */
78
79 bool showmethods = false;
80 bool showconstantpool = false;
81 bool showutf = false;
82
83 bool compileverbose =  false;
84 bool showstack = false;
85 bool showdisassemble = false; 
86 bool showddatasegment = false; 
87 bool showintermediate = false;
88
89 bool useinlining = false;
90 bool inlinevirtuals = false;
91 bool inlineexceptions = false;
92 bool inlineparamopt = false;
93 bool inlineoutsiders = false;
94
95 bool checkbounds = true;
96 bool checknull = true;
97 bool opt_noieee = false;
98 bool checksync = true;
99 bool opt_loops = false;
100
101 bool makeinitializations = true;
102
103 bool getloadingtime = false;   /* to measure the runtime                     */
104 s8 loadingtime = 0;
105
106 bool opt_verify = true;        /* true if classfiles should be verified      */
107
108
109 static classinfo *topclass;
110
111 #ifndef USE_THREADS
112 void **stackbottom = 0;
113 #endif
114
115
116 /* internal function: get_opt *************************************************
117         
118         decodes the next command line option
119         
120 ******************************************************************************/
121
122 #define OPT_DONE       -1
123 #define OPT_ERROR       0
124 #define OPT_IGNORE      1
125
126 #define OPT_CLASSPATH   2
127 #define OPT_D           3
128 #define OPT_MS          4
129 #define OPT_MX          5
130 #define OPT_VERBOSE1    6
131 #define OPT_VERBOSE     7
132 #define OPT_VERBOSEGC   8
133 #define OPT_VERBOSECALL 9
134 #define OPT_NOIEEE      10
135 #define OPT_SOFTNULL    11
136 #define OPT_TIME        12
137 #define OPT_STAT        13
138 #define OPT_LOG         14
139 #define OPT_CHECK       15
140 #define OPT_LOAD        16
141 #define OPT_METHOD      17
142 #define OPT_SIGNATURE   18
143 #define OPT_SHOW        19
144 #define OPT_ALL         20
145 #define OPT_OLOOP       24
146 #define OPT_INLINING    25
147 #define OPT_RT          26
148 #define OPT_XTA         27 
149 #define OPT_VTA         28
150 #define OPT_VERBOSETC   29
151 #define OPT_NOVERIFY    30
152
153
154 struct {char *name; bool arg; int value;} opts[] = {
155         {"classpath",   true,   OPT_CLASSPATH},
156         {"D",           true,   OPT_D},
157         {"ms",          true,   OPT_MS},
158         {"mx",          true,   OPT_MX},
159         {"noasyncgc",   false,  OPT_IGNORE},
160         {"noverify",    false,  OPT_NOVERIFY},
161         {"oss",         true,   OPT_IGNORE},
162         {"ss",          true,   OPT_IGNORE},
163         {"v",           false,  OPT_VERBOSE1},
164         {"verbose",     false,  OPT_VERBOSE},
165         {"verbosegc",   false,  OPT_VERBOSEGC},
166         {"verbosecall", false,  OPT_VERBOSECALL},
167 #ifdef TYPECHECK_VERBOSE
168         {"verbosetc",   false,  OPT_VERBOSETC},
169 #endif
170 #if defined(__ALPHA__)
171         {"noieee",      false,  OPT_NOIEEE},
172 #endif
173         {"softnull",    false,  OPT_SOFTNULL},
174         {"time",        false,  OPT_TIME},
175         {"stat",        false,  OPT_STAT},
176         {"log",         true,   OPT_LOG},
177         {"c",           true,   OPT_CHECK},
178         {"l",           false,  OPT_LOAD},
179         {"m",           true,   OPT_METHOD},
180         {"sig",         true,   OPT_SIGNATURE},
181         {"s",           true,   OPT_SHOW},
182         {"all",         false,  OPT_ALL},
183         {"oloop",       false,  OPT_OLOOP},
184         {"i",               true,   OPT_INLINING},
185         {"rt",          false,  OPT_RT},
186         {"xta",         false,  OPT_XTA},
187         {"vta",         false,  OPT_VTA},
188         {NULL,  false, 0}
189 };
190
191 static int opt_ind = 1;
192 static char *opt_arg;
193
194
195 static int get_opt(int argc, char **argv)
196 {
197         char *a;
198         int i;
199         
200         if (opt_ind >= argc) return OPT_DONE;
201         
202         a = argv[opt_ind];
203         if (a[0] != '-') return OPT_DONE;
204
205         for (i = 0; opts[i].name; i++) {
206                 if (!opts[i].arg) {
207                         if (strcmp(a + 1, opts[i].name) == 0) { /* boolean option found */
208                                 opt_ind++;
209                                 return opts[i].value;
210                         }
211
212                 } else {
213                         if (strcmp(a + 1, opts[i].name) == 0) { /* parameter option found */
214                                 opt_ind++;
215                                 if (opt_ind < argc) {
216                                         opt_arg = argv[opt_ind];
217                                         opt_ind++;
218                                         return opts[i].value;
219                                 }
220                                 return OPT_ERROR;
221
222                         } else {
223                                 size_t l = strlen(opts[i].name);
224                                 if (strlen(a + 1) > l) {
225                                         if (memcmp(a + 1, opts[i].name, l) == 0) {
226                                                 opt_ind++;
227                                                 opt_arg = a + 1 + l;
228                                                 return opts[i].value;
229                                         }
230                                 }
231                         }
232                 }
233         } /* end for */ 
234
235         return OPT_ERROR;
236 }
237
238
239
240
241 /******************** interne Function: print_usage ************************
242
243 Prints the correct usage syntax to stdout.
244
245 ***************************************************************************/
246
247 static void print_usage()
248 {
249         printf("USAGE: cacao [options] classname [program arguments]\n");
250         printf("Options:\n");
251         printf("          -classpath path ...... specify a path to look for classes\n");
252         printf("          -Dpropertyname=value . add an entry to the property list\n");
253         printf("          -mx maxmem[k|m] ...... specify the size for the heap\n");
254         printf("          -ms initmem[k|m] ..... specify the initial size for the heap\n");
255         printf("          -v ................... write state-information\n");
256         printf("          -verbose ............. write more information\n");
257         printf("          -verbosegc ........... write message for each GC\n");
258         printf("          -verbosecall ......... write message for each call\n");
259 #ifdef TYPECHECK_VERBOSE
260         printf("          -verbosetc ........... write debug messages while typechecking\n");
261 #endif
262 #if defined(__ALPHA__)
263         printf("          -noieee .............. don't use ieee compliant arithmetic\n");
264 #endif
265         printf("          -noverify ............ don't verify classfiles\n");
266         printf("          -softnull ............ use software nullpointer check\n");
267         printf("          -time ................ measure the runtime\n");
268         printf("          -stat ................ detailed compiler statistics\n");
269         printf("          -log logfile ......... specify a name for the logfile\n");
270         printf("          -c(heck)b(ounds) ..... don't check array bounds\n");
271         printf("                  s(ync) ....... don't check for synchronization\n");
272         printf("          -oloop ............... optimize array accesses in loops\n"); 
273         printf("          -l ................... don't start the class after loading\n");
274         printf("          -all ................. compile all methods, no execution\n");
275         printf("          -m ................... compile only a specific method\n");
276         printf("          -sig ................. specify signature for a specific method\n");
277         printf("          -s(how)a(ssembler) ... show disassembled listing\n");
278         printf("                 c(onstants) ... show the constant pool\n");
279         printf("                 d(atasegment).. show data segment listing\n");
280         printf("                 i(ntermediate). show intermediate representation\n");
281         printf("                 m(ethods)...... show class fields and methods\n");
282         printf("                 u(tf) ......... show the utf - hash\n");
283         printf("          -i     n ............. activate inlining\n");
284         printf("                 v ............. inline virtual methods\n");
285         printf("                 e ............. inline methods with exceptions\n");
286         printf("                 p ............. optimize argument renaming\n");
287         printf("                 o ............. inline methods of foreign classes\n");
288         printf("          -rt .................. use rapid type analysis\n");
289         printf("          -xta ................. use x type analysis\n");
290         printf("          -vta ................. use variable type analysis\n");
291 }   
292
293
294
295 /***************************** Function: print_times *********************
296
297         Prints a summary of CPU time usage.
298
299 **************************************************************************/
300
301 static void print_times()
302 {
303         s8 totaltime = getcputime();
304         s8 runtime = totaltime - loadingtime - compilingtime;
305         char logtext[MAXLOGTEXT];
306
307 #if defined(__I386__)
308         sprintf(logtext, "Time for loading classes: %lld secs, %lld millis",
309 #else
310         sprintf(logtext, "Time for loading classes: %ld secs, %ld millis",
311 #endif
312                         loadingtime / 1000000, (loadingtime % 1000000) / 1000);
313         log_text(logtext);
314
315 #if defined(__I386__)
316         sprintf(logtext, "Time for compiling code:  %lld secs, %lld millis",
317 #else
318         sprintf(logtext, "Time for compiling code:  %ld secs, %ld millis",
319 #endif
320                         compilingtime / 1000000, (compilingtime % 1000000) / 1000);
321         log_text(logtext);
322
323 #if defined(__I386__)
324         sprintf(logtext, "Time for running program: %lld secs, %lld millis",
325 #else
326         sprintf(logtext, "Time for running program: %ld secs, %ld millis",
327 #endif
328                         runtime / 1000000, (runtime % 1000000) / 1000);
329         log_text(logtext);
330
331 #if defined(__I386__)
332         sprintf(logtext, "Total time: %lld secs, %lld millis",
333 #else
334         sprintf(logtext, "Total time: %ld secs, %ld millis",
335 #endif
336                         totaltime / 1000000, (totaltime % 1000000) / 1000);
337         log_text(logtext);
338 }
339
340
341
342
343
344
345 /***************************** Function: print_stats *********************
346
347         outputs detailed compiler statistics
348
349 **************************************************************************/
350
351 static void print_stats()
352 {
353         char logtext[MAXLOGTEXT];
354
355         sprintf(logtext, "Number of JitCompiler Calls: %d", count_jit_calls);
356         log_text(logtext);
357         sprintf(logtext, "Number of compiled Methods: %d", count_methods);
358         log_text(logtext);
359         sprintf(logtext, "Number of max basic blocks per method: %d", count_max_basic_blocks);
360         log_text(logtext);
361         sprintf(logtext, "Number of compiled basic blocks: %d", count_basic_blocks);
362         log_text(logtext);
363         sprintf(logtext, "Number of max JavaVM-Instructions per method: %d", count_max_javainstr);
364         log_text(logtext);
365         sprintf(logtext, "Number of compiled JavaVM-Instructions: %d", count_javainstr);
366         log_text(logtext);
367         sprintf(logtext, "Size of compiled JavaVM-Instructions:   %d(%d)", count_javacodesize,
368                         count_javacodesize - count_methods * 18);
369         log_text(logtext);
370         sprintf(logtext, "Size of compiled Exception Tables:      %d", count_javaexcsize);
371         log_text(logtext);
372         sprintf(logtext, "Value of extended instruction set var:  %d", has_ext_instr_set);
373         log_text(logtext);
374         sprintf(logtext, "Number of Machine-Instructions: %d", count_code_len >> 2);
375         log_text(logtext);
376         sprintf(logtext, "Number of Spills: %d", count_spills);
377         log_text(logtext);
378         sprintf(logtext, "Number of Activ    Pseudocommands: %5d", count_pcmd_activ);
379         log_text(logtext);
380         sprintf(logtext, "Number of Drop     Pseudocommands: %5d", count_pcmd_drop);
381         log_text(logtext);
382         sprintf(logtext, "Number of Const    Pseudocommands: %5d (zero:%5d)", count_pcmd_load, count_pcmd_zero);
383         log_text(logtext);
384         sprintf(logtext, "Number of ConstAlu Pseudocommands: %5d (cmp: %5d, store:%5d)", count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
385         log_text(logtext);
386         sprintf(logtext, "Number of Move     Pseudocommands: %5d", count_pcmd_move);
387         log_text(logtext);
388         sprintf(logtext, "Number of Load     Pseudocommands: %5d", count_load_instruction);
389         log_text(logtext);
390         sprintf(logtext, "Number of Store    Pseudocommands: %5d (combined: %5d)", count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
391         log_text(logtext);
392         sprintf(logtext, "Number of OP       Pseudocommands: %5d", count_pcmd_op);
393         log_text(logtext);
394         sprintf(logtext, "Number of DUP      Pseudocommands: %5d", count_dup_instruction);
395         log_text(logtext);
396         sprintf(logtext, "Number of Mem      Pseudocommands: %5d", count_pcmd_mem);
397         log_text(logtext);
398         sprintf(logtext, "Number of Method   Pseudocommands: %5d", count_pcmd_met);
399         log_text(logtext);
400         sprintf(logtext, "Number of Branch   Pseudocommands: %5d (rets:%5d, Xrets: %5d)",
401                         count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
402         log_text(logtext);
403         sprintf(logtext, "Number of Table    Pseudocommands: %5d", count_pcmd_table);
404         log_text(logtext);
405         sprintf(logtext, "Number of Useful   Pseudocommands: %5d", count_pcmd_table +
406                         count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
407         log_text(logtext);
408         sprintf(logtext, "Number of Null Pointer Checks:     %5d", count_check_null);
409         log_text(logtext);
410         sprintf(logtext, "Number of Array Bound Checks:      %5d", count_check_bound);
411         log_text(logtext);
412         sprintf(logtext, "Number of Try-Blocks: %d", count_tryblocks);
413         log_text(logtext);
414         sprintf(logtext, "Maximal count of stack elements:   %d", count_max_new_stack);
415         log_text(logtext);
416         sprintf(logtext, "Upper bound of max stack elements: %d", count_upper_bound_new_stack);
417         log_text(logtext);
418         sprintf(logtext, "Distribution of stack sizes at block boundary");
419         log_text(logtext);
420         sprintf(logtext, "    0    1    2    3    4    5    6    7    8    9    >=10");
421         log_text(logtext);
422         sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_block_stack[0],
423                         count_block_stack[1], count_block_stack[2], count_block_stack[3], count_block_stack[4],
424                         count_block_stack[5], count_block_stack[6], count_block_stack[7], count_block_stack[8],
425                         count_block_stack[9], count_block_stack[10]);
426         log_text(logtext);
427         sprintf(logtext, "Distribution of store stack depth");
428         log_text(logtext);
429         sprintf(logtext, "    0    1    2    3    4    5    6    7    8    9    >=10");
430         log_text(logtext);
431         sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_depth[0],
432                         count_store_depth[1], count_store_depth[2], count_store_depth[3], count_store_depth[4],
433                         count_store_depth[5], count_store_depth[6], count_store_depth[7], count_store_depth[8],
434                         count_store_depth[9], count_store_depth[10]);
435         log_text(logtext);
436         sprintf(logtext, "Distribution of store creator chains first part");
437         log_text(logtext);
438         sprintf(logtext, "    0    1    2    3    4    5    6    7    8    9  ");
439         log_text(logtext);
440         sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[0],
441                         count_store_length[1], count_store_length[2], count_store_length[3], count_store_length[4],
442                         count_store_length[5], count_store_length[6], count_store_length[7], count_store_length[8],
443                         count_store_length[9]);
444         log_text(logtext);
445         sprintf(logtext, "Distribution of store creator chains second part");
446         log_text(logtext);
447         sprintf(logtext, "   10   11   12   13   14   15   16   17   18   19  >=20");
448         log_text(logtext);
449         sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[10],
450                         count_store_length[11], count_store_length[12], count_store_length[13], count_store_length[14],
451                         count_store_length[15], count_store_length[16], count_store_length[17], count_store_length[18],
452                         count_store_length[19], count_store_length[20]);
453         log_text(logtext);
454         sprintf(logtext, "Distribution of analysis iterations");
455         log_text(logtext);
456         sprintf(logtext, "    1    2    3    4    >=5");
457         log_text(logtext);
458         sprintf(logtext, "%5d%5d%5d%5d%5d", count_analyse_iterations[0], count_analyse_iterations[1],
459                         count_analyse_iterations[2], count_analyse_iterations[3], count_analyse_iterations[4]);
460         log_text(logtext);
461         sprintf(logtext, "Distribution of basic blocks per method");
462         log_text(logtext);
463         sprintf(logtext, " <= 5 <=10 <=15 <=20 <=30 <=40 <=50 <=75  >75");
464         log_text(logtext);
465         sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_method_bb_distribution[0],
466                         count_method_bb_distribution[1], count_method_bb_distribution[2], count_method_bb_distribution[3],
467                         count_method_bb_distribution[4], count_method_bb_distribution[5], count_method_bb_distribution[6],
468                         count_method_bb_distribution[7], count_method_bb_distribution[8]);
469         log_text(logtext);
470         sprintf(logtext, "Distribution of basic block sizes");
471         log_text(logtext);
472         sprintf(logtext,
473                          "  0    1    2    3    4   5   6   7   8   9 <13 <15 <17 <19 <21 <26 <31 >30");
474         log_text(logtext);
475         sprintf(logtext, "%3d%5d%5d%5d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d",
476                         count_block_size_distribution[0], count_block_size_distribution[1], count_block_size_distribution[2],
477                         count_block_size_distribution[3], count_block_size_distribution[4], count_block_size_distribution[5],
478                         count_block_size_distribution[6], count_block_size_distribution[7], count_block_size_distribution[8],
479                         count_block_size_distribution[9], count_block_size_distribution[10], count_block_size_distribution[11],
480                         count_block_size_distribution[12], count_block_size_distribution[13], count_block_size_distribution[14],
481                         count_block_size_distribution[15], count_block_size_distribution[16], count_block_size_distribution[17]);
482         log_text(logtext);
483         sprintf(logtext, "Size of Code Area (Kb):  %10.3f", (float) count_code_len / 1024);
484         log_text(logtext);
485         sprintf(logtext, "Size of data Area (Kb):  %10.3f", (float) count_data_len / 1024);
486         log_text(logtext);
487         sprintf(logtext, "Size of Class Infos (Kb):%10.3f", (float) (count_class_infos) / 1024);
488         log_text(logtext);
489         sprintf(logtext, "Size of Const Pool (Kb): %10.3f", (float) (count_const_pool_len + count_utf_len) / 1024);
490         log_text(logtext);
491         sprintf(logtext, "Size of Vftbl (Kb):      %10.3f", (float) count_vftbl_len / 1024);
492         log_text(logtext);
493         sprintf(logtext, "Size of comp stub (Kb):  %10.3f", (float) count_cstub_len / 1024);
494         log_text(logtext);
495         sprintf(logtext, "Size of native stub (Kb):%10.3f", (float) count_nstub_len / 1024);
496         log_text(logtext);
497         sprintf(logtext, "Size of Utf (Kb):        %10.3f", (float) count_utf_len / 1024);
498         log_text(logtext);
499         sprintf(logtext, "Size of VMCode (Kb):     %10.3f(%d)", (float) count_vmcode_len / 1024,
500                         count_vmcode_len - 18 * count_all_methods);
501         log_text(logtext);
502         sprintf(logtext, "Size of ExTable (Kb):    %10.3f", (float) count_extable_len / 1024);
503         log_text(logtext);
504         sprintf(logtext, "Number of class loads:   %d", count_class_loads);
505         log_text(logtext);
506         sprintf(logtext, "Number of class inits:   %d", count_class_inits);
507         log_text(logtext);
508         sprintf(logtext, "Number of loaded Methods: %d\n\n", count_all_methods);
509         log_text(logtext);
510
511         sprintf(logtext, "Calls of utf_new: %22d", count_utf_new);
512         log_text(logtext);
513         sprintf(logtext, "Calls of utf_new (element found): %6d\n\n", count_utf_new_found);
514         log_text(logtext);
515 }
516
517
518
519 /********** Function: class_compile_methods   (debugging only) ********/
520
521 void class_compile_methods ()
522 {
523         int        i;
524         classinfo  *c;
525         methodinfo *m;
526         
527         c = list_first (&linkedclasses);
528         while (c) {
529                 for (i = 0; i < c -> methodscount; i++) {
530                         m = &(c->methods[i]);
531                         if (m->jcode) {
532                                 (void) jit_compile(m);
533                         }
534                 }
535                 c = list_next(&linkedclasses, c);
536         }
537 }
538
539
540
541 /*
542  * void exit_handler(void)
543  * -----------------------
544  * The exit_handler function is called upon program termination to shutdown
545  * the various subsystems and release the resources allocated to the VM.
546  */
547 void exit_handler(void)
548 {
549         /********************* Print debug tables ************************/
550                                 
551         if (showmethods) class_showmethods(topclass);
552         if (showconstantpool) class_showconstantpool(topclass);
553         if (showutf) utf_show();
554
555 #ifdef USE_THREADS
556         clear_thread_flags();           /* restores standard file descriptor
557                                        flags */
558 #endif
559
560         /************************ Free all resources *******************/
561
562         heap_close();               /* must be called before compiler_close and
563                                        loader_close because finalization occurs
564                                        here */
565
566         loader_close();
567         tables_close(literalstring_free);
568
569         if (verbose || getcompilingtime || statistics) {
570                 log_text("CACAO terminated");
571                 if (statistics)
572                         print_stats();
573                 if (getcompilingtime)
574                         print_times();
575                 mem_usagelog(1);
576         }
577 }
578
579
580 /************************** Function: main *******************************
581
582    The main program.
583    
584 **************************************************************************/
585
586 int main(int argc, char **argv)
587 {
588         s4 i, j;
589         char *cp;
590         void *dummy;
591         
592         /********** interne (nur fuer main relevante Optionen) **************/
593    
594         char logfilename[200] = "";
595         u4 heapsize = 64000000;
596         u4 heapstartsize = 200000;
597         char classpath[500] = ".";
598         bool startit = true;
599         char *specificmethodname = NULL;
600         char *specificsignature = NULL;
601
602 #ifndef USE_THREADS
603         stackbottom = &dummy;
604 #endif
605         
606         if (0 != atexit(exit_handler))
607                 panic("unable to register exit_handler");
608
609         /************ Collect info from the environment ************************/
610
611         cp = getenv("CLASSPATH");
612         if (cp) {
613                 strcpy(classpath, cp);
614         }
615
616         /***************** Interpret the command line *****************/
617    
618         checknull = false;
619         opt_noieee = false;
620
621         while ((i = get_opt(argc, argv)) != OPT_DONE) {
622                 switch (i) {
623                 case OPT_IGNORE: break;
624                         
625                 case OPT_CLASSPATH:    
626                         strcpy(classpath + strlen(classpath), ":");
627                         strcpy(classpath + strlen(classpath), opt_arg);
628                         break;
629                                 
630                 case OPT_D:
631                         {
632                                 int n;
633                                 int l = strlen(opt_arg);
634                                 for (n = 0; n < l; n++) {
635                                         if (opt_arg[n] == '=') {
636                                                 opt_arg[n] = '\0';
637                                                 attach_property(opt_arg, opt_arg + n + 1);
638                                                 goto didit;
639                                         }
640                                 }
641                                 print_usage();
642                                 exit(10);
643                                         
644                         didit: ;
645                         }       
646                         break;
647                                 
648                 case OPT_MS:
649                 case OPT_MX:
650                         if (opt_arg[strlen(opt_arg) - 1] == 'k') {
651                                 j = 1024 * atoi(opt_arg);
652                         }
653                         else if (opt_arg[strlen(opt_arg) - 1] == 'm') {
654                                 j = 1024 * 1024 * atoi(opt_arg);
655                         }
656                         else j = atoi(opt_arg);
657                                 
658                         if (i == OPT_MX) heapsize = j;
659                         else heapstartsize = j;
660                         break;
661
662                 case OPT_VERBOSE1:
663                         verbose = true;
664                         break;
665                                                                 
666                 case OPT_VERBOSE:
667                         verbose = true;
668                         loadverbose = true;
669                         initverbose = true;
670                         compileverbose = true;
671                         break;
672                                 
673                 case OPT_VERBOSEGC:
674                         collectverbose = true;
675                         break;
676
677 #ifdef TYPECHECK_VERBOSE
678                 case OPT_VERBOSETC:
679                         typecheckverbose = true;
680                         break;
681 #endif
682                                 
683                 case OPT_VERBOSECALL:
684                         runverbose = true;
685                         break;
686                                 
687                 case OPT_NOIEEE:
688                         opt_noieee = true;
689                         break;
690
691                 case OPT_NOVERIFY:
692                         opt_verify = false;
693                         break;
694
695                 case OPT_SOFTNULL:
696                         checknull = true;
697                         break;
698
699                 case OPT_TIME:
700                         getcompilingtime = true;
701                         getloadingtime = true;
702                         break;
703                                         
704                 case OPT_STAT:
705                         statistics = true;
706                         break;
707                                         
708                 case OPT_LOG:
709                         strcpy(logfilename, opt_arg);
710                         break;
711                         
712                 case OPT_CHECK:
713                         for (j = 0; j < strlen(opt_arg); j++) {
714                                 switch (opt_arg[j]) {
715                                 case 'b':
716                                         checkbounds = false;
717                                         break;
718                                 case 's':
719                                         checksync = false;
720                                         break;
721                                 default:
722                                         print_usage();
723                                         exit(10);
724                                 }
725                         }
726                         break;
727                         
728                 case OPT_LOAD:
729                         startit = false;
730                         makeinitializations = false;
731                         break;
732
733                 case OPT_METHOD:
734                         startit = false;
735                         specificmethodname = opt_arg;                   
736                         makeinitializations = false;
737                         break;
738                         
739                 case OPT_SIGNATURE:
740                         specificsignature = opt_arg;                    
741                         break;
742                         
743                 case OPT_ALL:
744                         compileall = true;              
745                         startit = false;
746                         makeinitializations = false;
747                         break;
748                         
749                 case OPT_SHOW:       /* Display options */
750                         for (j = 0; j < strlen(opt_arg); j++) {         
751                                 switch (opt_arg[j]) {
752                                 case 'a':
753                                         showdisassemble = true;
754                                         compileverbose=true;
755                                         break;
756                                 case 'c':
757                                         showconstantpool = true;
758                                         break;
759                                 case 'd':
760                                         showddatasegment = true;
761                                         break;
762                                 case 'i':
763                                         showintermediate = true;
764                                         compileverbose = true;
765                                         break;
766                                 case 'm':
767                                         showmethods = true;
768                                         break;
769                                 case 'u':
770                                         showutf = true;
771                                         break;
772                                 default:
773                                         print_usage();
774                                         exit(10);
775                                 }
776                         }
777                         break;
778                         
779                 case OPT_OLOOP:
780                         opt_loops = true;
781                         break;
782
783                 case OPT_INLINING:
784                         for (j = 0; j < strlen(opt_arg); j++) {         
785                                 switch (opt_arg[j]) {
786                                 case 'n':
787                                         useinlining = true;
788                                         break;
789                                 case 'v':
790                                         inlinevirtuals = true;
791                                         break;
792                                 case 'e':
793                                         inlineexceptions = true;
794                                         break;
795                                 case 'p':
796                                         inlineparamopt = true;
797                                         break;
798                                 case 'o':
799                                         inlineoutsiders = true;
800                                         break;
801                                 default:
802                                         print_usage();
803                                         exit(10);
804                                 }
805                         }
806                         break;
807
808                 case OPT_RT:
809                         opt_rt = true;
810                         break;
811
812                 case OPT_XTA:
813                         opt_xta = false; /**not yet **/
814                         break;
815
816                 case OPT_VTA:
817                         /***opt_vta = true; not yet **/
818                         break;
819
820                 default:
821                         print_usage();
822                         exit(10);
823                 }
824         }
825    
826    
827         if (opt_ind >= argc) {
828                 print_usage();
829                 exit(10);
830         }
831
832
833         /**************************** Program start *****************************/
834
835         log_init(logfilename);
836         if (verbose) {
837                 log_text("CACAO started -------------------------------------------------------");
838         }
839
840         suck_init(classpath);
841         native_setclasspath(classpath);
842                 
843         tables_init();
844         heap_init(heapsize, heapstartsize, &dummy);
845
846         log_text("calling jit_init");
847         jit_init();
848
849         log_text("calling loader_init");
850         loader_init((u1 *) &dummy);
851
852         log_text("calling native_loadclasses");
853         native_loadclasses();
854
855
856         /*********************** Load JAVA classes  ***************************/
857    
858         cp = argv[opt_ind++];
859         for (i = strlen(cp) - 1; i >= 0; i--) {     /* Transform dots into slashes */
860                 if (cp[i] == '.') cp[i] = '/';          /* in the class name */
861         }
862
863         topclass = loader_load(utf_new_char(cp));
864
865         if (exceptionptr != 0) {
866                 printf("Exception in thread \"main\" ");
867                 utf_display(exceptionptr->vftbl->class->name);
868                 printf(": ");
869                 utf_display(javastring_toutf(((java_lang_Throwable *) exceptionptr)->detailMessage, false));
870                 printf("\n");
871
872                 exceptionptr = 0;
873         }
874
875         if (topclass == 0) {
876                 /* should we print out something? we already have the exception */
877                 exit(1);
878         }
879
880         /* initialize the garbage collector */
881         gc_init();
882
883 #ifdef USE_THREADS
884         initThreads((u1*) &dummy);
885 #endif
886
887
888         /************************* Start worker routines ********************/
889
890         if (startit) {
891                 methodinfo *mainmethod;
892                 java_objectarray *a; 
893
894 /*              heap_addreference((void**) &a); */
895
896                 mainmethod = class_findmethod(topclass,
897                                                                           utf_new_char("main"), 
898                                                                           utf_new_char("([Ljava/lang/String;)V")
899                                                                           );
900
901                 /* there is no main method or it isn't static */
902                 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
903                         printf("Exception in thread \"main\" java.lang.NoSuchMethodError: main\n");
904                         exit(1);
905                 }
906
907                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
908                 for (i = opt_ind; i < argc; i++) {
909                         a->data[i - opt_ind] = 
910                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
911                 }
912
913 #ifdef TYPEINFO_DEBUG_TEST
914                 /* test the typeinfo system */
915                 typeinfo_test();
916 #endif
917                 /*class_showmethods(currentThread->group->header.vftbl->class); */
918
919                 /* here we go... */
920                 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
921         
922                 if (exceptionptr) {
923                         printf("Exception in thread \"main\" ");
924                         utf_display(exceptionptr->vftbl->class->name);
925
926                         /* do we have a detail message? */
927                         if (((java_lang_Throwable *) exceptionptr)->detailMessage) {
928                                 printf(": ");
929                                 utf_display(javastring_toutf(((java_lang_Throwable *) exceptionptr)->detailMessage, false));
930                         }
931                         printf("\n");
932                 }
933
934 #ifdef USE_THREADS
935                 killThread(currentThread);
936 #endif
937                 fprintf(stderr, "still here\n");
938         }
939
940         /************* If requested, compile all methods ********************/
941
942         if (compileall) {
943                 class_compile_methods();
944         }
945
946
947         /******** If requested, compile a specific method ***************/
948
949         if (specificmethodname) {
950                 methodinfo *m;
951                 if (specificsignature) {
952                         m = class_findmethod(topclass, 
953                                                                  utf_new_char(specificmethodname),
954                                                                  utf_new_char(specificsignature));
955                 } else {
956                         m = class_findmethod(topclass, 
957                                                                  utf_new_char(specificmethodname),
958                                                                  NULL);
959                 }
960
961                 if (!m)
962                         panic("Specific method not found");
963                 
964                 jit_compile(m);
965         }
966
967         exit(0);
968 }
969
970
971
972 /************************************ Shutdown function *********************************
973
974         Terminates the system immediately without freeing memory explicitly (to be
975         used only for abnormal termination)
976         
977 *****************************************************************************************/
978
979 void cacao_shutdown(s4 status)
980 {
981         /**** RTAprint ***/
982
983         if (verbose || getcompilingtime || statistics) {
984                 log_text ("CACAO terminated by shutdown");
985                 if (statistics)
986                         print_stats();
987                 if (getcompilingtime)
988                         print_times();
989                 mem_usagelog(0);
990                 dolog("Exit status: %d\n", (int) status);
991         }
992
993         exit(status);
994 }
995
996
997 /*
998  * These are local overrides for various environment variables in Emacs.
999  * Please do not remove this and leave it at the end of the file, where
1000  * Emacs will automagically detect them.
1001  * ---------------------------------------------------------------------
1002  * Local variables:
1003  * mode: c
1004  * indent-tabs-mode: t
1005  * c-basic-offset: 4
1006  * tab-width: 4
1007  * End:
1008  */