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