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