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