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