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