1 /* main.c - contains main() and variables for the global options
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,
9 This file is part of CACAO.
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.
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.
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
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Reinhard Grafl
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
40 $Id: cacao.c 1173 2004-06-16 14:56:18Z jowenn $
56 #include "threads/thread.h"
57 #include "toolbox/logging.h"
58 #include "toolbox/memory.h"
59 #include "jit/parseRTstats.h"
60 #include "nat/java_io_File.h" /* required by java_lang_Runtime.h */
61 #include "nat/java_util_Properties.h" /* required by java_lang_Runtime.h */
62 #include "nat/java_lang_Runtime.h"
63 #include "nat/java_lang_Throwable.h"
65 #ifdef TYPEINFO_DEBUG_TEST
70 bool cacao_initializing;
72 /* command line option */
74 bool compileall = false;
75 bool runverbose = false; /* trace all method invocation */
76 bool verboseexception = false;
77 bool collectverbose = false;
79 bool loadverbose = false;
80 bool linkverbose = false;
81 bool initverbose = false;
83 bool opt_rt = false; /* true if RTA parse should be used RT-CO */
84 bool opt_xta = false; /* true if XTA parse should be used XTA-CO */
85 bool opt_vta = false; /* true if VTA parse should be used VTA-CO */
87 bool opt_liberalutf = false; /* Don't check overlong UTF-8 sequences */
89 bool showmethods = false;
90 bool showconstantpool = false;
93 bool compileverbose = false; /* trace compiler actions */
94 bool showstack = false;
95 bool showdisassemble = false; /* generate disassembler listing */
96 bool showddatasegment = false; /* generate data segment listing */
97 bool showintermediate = false; /* generate intermediate code listing */
99 bool useinlining = false; /* use method inlining */
100 bool inlinevirtuals = false; /* inline unique virtual methods */
101 bool inlineexceptions = false; /* inline methods, that contain excptions */
102 bool inlineparamopt = false; /* optimize parameter passing to inlined methods */
103 bool inlineoutsiders = false; /* inline methods, that are not member of the invoker's class */
105 bool checkbounds = true; /* check array bounds */
106 bool checknull = true; /* check null pointers */
107 bool opt_noieee = false; /* don't implement ieee compliant floats */
108 bool checksync = true; /* do synchronization */
109 bool opt_loops = false; /* optimize array accesses in loops */
111 bool makeinitializations = true;
113 bool getloadingtime = false; /* to measure the runtime */
116 bool getcompilingtime = false; /* compute compile time */
117 s8 compilingtime = 0; /* accumulated compile time */
119 int has_ext_instr_set = 0; /* has instruction set extensions */
121 bool opt_stat = false;
123 bool opt_verify = true; /* true if classfiles should be verified */
125 bool opt_eager = false;
128 static classinfo *mainclass;
130 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
131 void **stackbottom = 0;
135 /* internal function: get_opt *************************************************
137 decodes the next command line option
139 ******************************************************************************/
145 #define OPT_CLASSPATH 2
149 #define OPT_VERBOSE1 6
150 #define OPT_VERBOSE 7
151 #define OPT_VERBOSEGC 8
152 #define OPT_VERBOSECALL 9
153 #define OPT_NOIEEE 10
154 #define OPT_SOFTNULL 11
160 #define OPT_METHOD 17
161 #define OPT_SIGNATURE 18
165 #define OPT_INLINING 25
169 #define OPT_VERBOSETC 29
170 #define OPT_NOVERIFY 30
171 #define OPT_LIBERALUTF 31
172 #define OPT_VERBOSEEXCEPTION 32
176 struct {char *name; bool arg; int value;} opts[] = {
177 {"classpath", true, OPT_CLASSPATH},
179 {"ms", true, OPT_MS},
180 {"mx", true, OPT_MX},
181 {"noasyncgc", false, OPT_IGNORE},
182 {"noverify", false, OPT_NOVERIFY},
183 {"liberalutf", false, OPT_LIBERALUTF},
184 {"oss", true, OPT_IGNORE},
185 {"ss", true, OPT_IGNORE},
186 {"v", false, OPT_VERBOSE1},
187 {"verbose", false, OPT_VERBOSE},
188 {"verbosegc", false, OPT_VERBOSEGC},
189 {"verbosecall", false, OPT_VERBOSECALL},
190 {"verboseexception", false, OPT_VERBOSEEXCEPTION},
191 #ifdef TYPECHECK_VERBOSE
192 {"verbosetc", false, OPT_VERBOSETC},
194 #if defined(__ALPHA__)
195 {"noieee", false, OPT_NOIEEE},
197 {"softnull", false, OPT_SOFTNULL},
198 {"time", false, OPT_TIME},
199 {"stat", false, OPT_STAT},
200 {"log", true, OPT_LOG},
201 {"c", true, OPT_CHECK},
202 {"l", false, OPT_LOAD},
203 { "eager", false, OPT_EAGER },
204 {"m", true, OPT_METHOD},
205 {"sig", true, OPT_SIGNATURE},
206 {"s", true, OPT_SHOW},
207 {"all", false, OPT_ALL},
208 {"oloop", false, OPT_OLOOP},
209 {"i", true, OPT_INLINING},
210 {"rt", false, OPT_RT},
211 {"xta", false, OPT_XTA},
212 {"vta", false, OPT_VTA},
216 static int opt_ind = 1;
217 static char *opt_arg;
220 static int get_opt(int argc, char **argv)
225 if (opt_ind >= argc) return OPT_DONE;
228 if (a[0] != '-') return OPT_DONE;
230 for (i = 0; opts[i].name; i++) {
232 if (strcmp(a + 1, opts[i].name) == 0) { /* boolean option found */
234 return opts[i].value;
238 if (strcmp(a + 1, opts[i].name) == 0) { /* parameter option found */
240 if (opt_ind < argc) {
241 opt_arg = argv[opt_ind];
243 return opts[i].value;
248 size_t l = strlen(opts[i].name);
249 if (strlen(a + 1) > l) {
250 if (memcmp(a + 1, opts[i].name, l) == 0) {
253 return opts[i].value;
264 /******************** interne Function: print_usage ************************
266 Prints the correct usage syntax to stdout.
268 ***************************************************************************/
270 static void print_usage()
272 printf("USAGE: cacao [options] classname [program arguments]\n");
273 printf("Options:\n");
274 printf(" -classpath path ...... specify a path to look for classes\n");
275 printf(" -Dpropertyname=value . add an entry to the property list\n");
276 printf(" -mx maxmem[k|m] ...... specify the size for the heap\n");
277 printf(" -ms initmem[k|m] ..... specify the initial size for the heap\n");
278 printf(" -v ................... write state-information\n");
279 printf(" -verbose ............. write more information\n");
280 printf(" -verbosegc ........... write message for each GC\n");
281 printf(" -verbosecall ......... write message for each call\n");
282 printf(" -verboseexception .... write message for each step of stack unwinding\n");
283 #ifdef TYPECHECK_VERBOSE
284 printf(" -verbosetc ........... write debug messages while typechecking\n");
286 #if defined(__ALPHA__)
287 printf(" -noieee .............. don't use ieee compliant arithmetic\n");
289 printf(" -noverify ............ don't verify classfiles\n");
290 printf(" -liberalutf........... don't warn about overlong UTF-8 sequences\n");
291 printf(" -softnull ............ use software nullpointer check\n");
292 printf(" -time ................ measure the runtime\n");
293 printf(" -stat ................ detailed compiler statistics\n");
294 printf(" -log logfile ......... specify a name for the logfile\n");
295 printf(" -c(heck)b(ounds) ..... don't check array bounds\n");
296 printf(" s(ync) ....... don't check for synchronization\n");
297 printf(" -oloop ............... optimize array accesses in loops\n");
298 printf(" -l ................... don't start the class after loading\n");
299 printf(" -eager perform eager class loading and linking\n");
300 printf(" -all ................. compile all methods, no execution\n");
301 printf(" -m ................... compile only a specific method\n");
302 printf(" -sig ................. specify signature for a specific method\n");
303 printf(" -s(how)a(ssembler) ... show disassembled listing\n");
304 printf(" c(onstants) ... show the constant pool\n");
305 printf(" d(atasegment).. show data segment listing\n");
306 printf(" i(ntermediate). show intermediate representation\n");
307 printf(" m(ethods)...... show class fields and methods\n");
308 printf(" u(tf) ......... show the utf - hash\n");
309 printf(" -i n ............. activate inlining\n");
310 printf(" v ............. inline virtual methods\n");
311 printf(" e ............. inline methods with exceptions\n");
312 printf(" p ............. optimize argument renaming\n");
313 printf(" o ............. inline methods of foreign classes\n");
314 printf(" -rt .................. use rapid type analysis\n");
315 printf(" -xta ................. use x type analysis\n");
316 printf(" -vta ................. use variable type analysis\n");
320 /***************************** Function: print_times *********************
322 Prints a summary of CPU time usage.
324 **************************************************************************/
326 static void print_times()
328 s8 totaltime = getcputime();
329 s8 runtime = totaltime - loadingtime - compilingtime;
330 char logtext[MAXLOGTEXT];
332 #if defined(__I386__) || defined(__POWERPC__)
333 sprintf(logtext, "Time for loading classes: %lld secs, %lld millis",
335 sprintf(logtext, "Time for loading classes: %ld secs, %ld millis",
337 loadingtime / 1000000, (loadingtime % 1000000) / 1000);
340 #if defined(__I386__) || defined(__POWERPC__)
341 sprintf(logtext, "Time for compiling code: %lld secs, %lld millis",
343 sprintf(logtext, "Time for compiling code: %ld secs, %ld millis",
345 compilingtime / 1000000, (compilingtime % 1000000) / 1000);
348 #if defined(__I386__) || defined(__POWERPC__)
349 sprintf(logtext, "Time for running program: %lld secs, %lld millis",
351 sprintf(logtext, "Time for running program: %ld secs, %ld millis",
353 runtime / 1000000, (runtime % 1000000) / 1000);
356 #if defined(__I386__) || defined(__POWERPC__)
357 sprintf(logtext, "Total time: %lld secs, %lld millis",
359 sprintf(logtext, "Total time: %ld secs, %ld millis",
361 totaltime / 1000000, (totaltime % 1000000) / 1000);
366 /***************************** Function: print_stats *********************
368 outputs detailed compiler statistics
370 **************************************************************************/
372 static void print_stats()
374 char logtext[MAXLOGTEXT];
376 sprintf(logtext, "Number of JitCompiler Calls: %d", count_jit_calls);
378 sprintf(logtext, "Number of compiled Methods: %d", count_methods);
380 sprintf(logtext, "Number of max basic blocks per method: %d", count_max_basic_blocks);
382 sprintf(logtext, "Number of compiled basic blocks: %d", count_basic_blocks);
384 sprintf(logtext, "Number of max JavaVM-Instructions per method: %d", count_max_javainstr);
386 sprintf(logtext, "Number of compiled JavaVM-Instructions: %d", count_javainstr);
388 sprintf(logtext, "Size of compiled JavaVM-Instructions: %d(%d)", count_javacodesize,
389 count_javacodesize - count_methods * 18);
391 sprintf(logtext, "Size of compiled Exception Tables: %d", count_javaexcsize);
393 sprintf(logtext, "Value of extended instruction set var: %d", has_ext_instr_set);
395 sprintf(logtext, "Number of Machine-Instructions: %d", count_code_len >> 2);
397 sprintf(logtext, "Number of Spills: %d", count_spills);
399 sprintf(logtext, "Number of Activ Pseudocommands: %5d", count_pcmd_activ);
401 sprintf(logtext, "Number of Drop Pseudocommands: %5d", count_pcmd_drop);
403 sprintf(logtext, "Number of Const Pseudocommands: %5d (zero:%5d)", count_pcmd_load, count_pcmd_zero);
405 sprintf(logtext, "Number of ConstAlu Pseudocommands: %5d (cmp: %5d, store:%5d)", count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
407 sprintf(logtext, "Number of Move Pseudocommands: %5d", count_pcmd_move);
409 sprintf(logtext, "Number of Load Pseudocommands: %5d", count_load_instruction);
411 sprintf(logtext, "Number of Store Pseudocommands: %5d (combined: %5d)", count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
413 sprintf(logtext, "Number of OP Pseudocommands: %5d", count_pcmd_op);
415 sprintf(logtext, "Number of DUP Pseudocommands: %5d", count_dup_instruction);
417 sprintf(logtext, "Number of Mem Pseudocommands: %5d", count_pcmd_mem);
419 sprintf(logtext, "Number of Method Pseudocommands: %5d", count_pcmd_met);
421 sprintf(logtext, "Number of Branch Pseudocommands: %5d (rets:%5d, Xrets: %5d)",
422 count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
424 sprintf(logtext, "Number of Table Pseudocommands: %5d", count_pcmd_table);
426 sprintf(logtext, "Number of Useful Pseudocommands: %5d", count_pcmd_table +
427 count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
429 sprintf(logtext, "Number of Null Pointer Checks: %5d", count_check_null);
431 sprintf(logtext, "Number of Array Bound Checks: %5d", count_check_bound);
433 sprintf(logtext, "Number of Try-Blocks: %d", count_tryblocks);
435 sprintf(logtext, "Maximal count of stack elements: %d", count_max_new_stack);
437 sprintf(logtext, "Upper bound of max stack elements: %d", count_upper_bound_new_stack);
439 sprintf(logtext, "Distribution of stack sizes at block boundary");
441 sprintf(logtext, " 0 1 2 3 4 5 6 7 8 9 >=10");
443 sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_block_stack[0],
444 count_block_stack[1], count_block_stack[2], count_block_stack[3], count_block_stack[4],
445 count_block_stack[5], count_block_stack[6], count_block_stack[7], count_block_stack[8],
446 count_block_stack[9], count_block_stack[10]);
448 sprintf(logtext, "Distribution of store stack depth");
450 sprintf(logtext, " 0 1 2 3 4 5 6 7 8 9 >=10");
452 sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_depth[0],
453 count_store_depth[1], count_store_depth[2], count_store_depth[3], count_store_depth[4],
454 count_store_depth[5], count_store_depth[6], count_store_depth[7], count_store_depth[8],
455 count_store_depth[9], count_store_depth[10]);
457 sprintf(logtext, "Distribution of store creator chains first part");
459 sprintf(logtext, " 0 1 2 3 4 5 6 7 8 9 ");
461 sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[0],
462 count_store_length[1], count_store_length[2], count_store_length[3], count_store_length[4],
463 count_store_length[5], count_store_length[6], count_store_length[7], count_store_length[8],
464 count_store_length[9]);
466 sprintf(logtext, "Distribution of store creator chains second part");
468 sprintf(logtext, " 10 11 12 13 14 15 16 17 18 19 >=20");
470 sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_store_length[10],
471 count_store_length[11], count_store_length[12], count_store_length[13], count_store_length[14],
472 count_store_length[15], count_store_length[16], count_store_length[17], count_store_length[18],
473 count_store_length[19], count_store_length[20]);
475 sprintf(logtext, "Distribution of analysis iterations");
477 sprintf(logtext, " 1 2 3 4 >=5");
479 sprintf(logtext, "%5d%5d%5d%5d%5d", count_analyse_iterations[0], count_analyse_iterations[1],
480 count_analyse_iterations[2], count_analyse_iterations[3], count_analyse_iterations[4]);
482 sprintf(logtext, "Distribution of basic blocks per method");
484 sprintf(logtext, " <= 5 <=10 <=15 <=20 <=30 <=40 <=50 <=75 >75");
486 sprintf(logtext, "%5d%5d%5d%5d%5d%5d%5d%5d%5d", count_method_bb_distribution[0],
487 count_method_bb_distribution[1], count_method_bb_distribution[2], count_method_bb_distribution[3],
488 count_method_bb_distribution[4], count_method_bb_distribution[5], count_method_bb_distribution[6],
489 count_method_bb_distribution[7], count_method_bb_distribution[8]);
491 sprintf(logtext, "Distribution of basic block sizes");
494 " 0 1 2 3 4 5 6 7 8 9 <13 <15 <17 <19 <21 <26 <31 >30");
496 sprintf(logtext, "%3d%5d%5d%5d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d",
497 count_block_size_distribution[0], count_block_size_distribution[1], count_block_size_distribution[2],
498 count_block_size_distribution[3], count_block_size_distribution[4], count_block_size_distribution[5],
499 count_block_size_distribution[6], count_block_size_distribution[7], count_block_size_distribution[8],
500 count_block_size_distribution[9], count_block_size_distribution[10], count_block_size_distribution[11],
501 count_block_size_distribution[12], count_block_size_distribution[13], count_block_size_distribution[14],
502 count_block_size_distribution[15], count_block_size_distribution[16], count_block_size_distribution[17]);
504 sprintf(logtext, "Size of Code Area (Kb): %10.3f", (float) count_code_len / 1024);
506 sprintf(logtext, "Size of data Area (Kb): %10.3f", (float) count_data_len / 1024);
508 sprintf(logtext, "Size of Class Infos (Kb):%10.3f", (float) (count_class_infos) / 1024);
510 sprintf(logtext, "Size of Const Pool (Kb): %10.3f", (float) (count_const_pool_len + count_utf_len) / 1024);
512 sprintf(logtext, "Size of Vftbl (Kb): %10.3f", (float) count_vftbl_len / 1024);
514 sprintf(logtext, "Size of comp stub (Kb): %10.3f", (float) count_cstub_len / 1024);
516 sprintf(logtext, "Size of native stub (Kb):%10.3f", (float) count_nstub_len / 1024);
518 sprintf(logtext, "Size of Utf (Kb): %10.3f", (float) count_utf_len / 1024);
520 sprintf(logtext, "Size of VMCode (Kb): %10.3f(%d)", (float) count_vmcode_len / 1024,
521 count_vmcode_len - 18 * count_all_methods);
523 sprintf(logtext, "Size of ExTable (Kb): %10.3f", (float) count_extable_len / 1024);
525 sprintf(logtext, "Number of class loads: %d", count_class_loads);
527 sprintf(logtext, "Number of class inits: %d", count_class_inits);
529 sprintf(logtext, "Number of loaded Methods: %d\n\n", count_all_methods);
532 sprintf(logtext, "Calls of utf_new: %22d", count_utf_new);
534 sprintf(logtext, "Calls of utf_new (element found): %6d\n\n", count_utf_new_found);
539 #ifdef TYPECHECK_STATISTICS
540 void typecheck_print_statistics(FILE *file);
545 * void exit_handler(void)
546 * -----------------------
547 * The exit_handler function is called upon program termination to shutdown
548 * the various subsystems and release the resources allocated to the VM.
550 void exit_handler(void)
552 /********************* Print debug tables ************************/
554 if (showmethods) class_showmethods(mainclass);
555 if (showconstantpool) class_showconstantpool(mainclass);
556 if (showutf) utf_show();
558 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
559 clear_thread_flags(); /* restores standard file descriptor
563 /************************ Free all resources *******************/
565 /*heap_close();*/ /* must be called before compiler_close and
566 loader_close because finalization occurs
570 tables_close(literalstring_free);
572 if (verbose || getcompilingtime || opt_stat) {
573 log_text("CACAO terminated");
576 #ifdef TYPECHECK_STATISTICS
577 typecheck_print_statistics(get_logfile());
580 if (getcompilingtime)
587 /************************** Function: main *******************************
591 **************************************************************************/
593 int main(int argc, char **argv)
598 /********** interne (nur fuer main relevante Optionen) **************/
600 char logfilename[200] = "";
601 u4 heapmaxsize = 64 * 1024 * 1024;
602 u4 heapstartsize = 200 * 1024;
604 char classpath[500] = ".";
606 char *specificmethodname = NULL;
607 char *specificsignature = NULL;
609 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
610 stackbottom = &dummy;
613 if (0 != atexit(exit_handler))
614 throw_cacao_exception_exit(string_java_lang_InternalError,
615 "unable to register exit_handler");
618 /************ Collect info from the environment ************************/
620 cp = getenv("CLASSPATH");
622 strcpy(classpath, cp);
625 /***************** Interpret the command line *****************/
630 while ((i = get_opt(argc, argv)) != OPT_DONE) {
632 case OPT_IGNORE: break;
635 strcpy(classpath + strlen(classpath), ":");
636 strcpy(classpath + strlen(classpath), opt_arg);
642 int l = strlen(opt_arg);
643 for (n = 0; n < l; n++) {
644 if (opt_arg[n] == '=') {
646 attach_property(opt_arg, opt_arg + n + 1);
659 if (opt_arg[strlen(opt_arg) - 1] == 'k') {
660 j = 1024 * atoi(opt_arg);
662 } else if (opt_arg[strlen(opt_arg) - 1] == 'm') {
663 j = 1024 * 1024 * atoi(opt_arg);
665 } else j = atoi(opt_arg);
667 if (i == OPT_MX) heapmaxsize = j;
668 else heapstartsize = j;
680 compileverbose = true;
683 case OPT_VERBOSEEXCEPTION:
684 verboseexception = true;
688 collectverbose = true;
691 #ifdef TYPECHECK_VERBOSE
693 typecheckverbose = true;
697 case OPT_VERBOSECALL:
710 opt_liberalutf = true;
718 getcompilingtime = true;
719 getloadingtime = true;
727 strcpy(logfilename, opt_arg);
731 for (j = 0; j < strlen(opt_arg); j++) {
732 switch (opt_arg[j]) {
748 makeinitializations = false;
757 specificmethodname = opt_arg;
758 makeinitializations = false;
762 specificsignature = opt_arg;
768 makeinitializations = false;
771 case OPT_SHOW: /* Display options */
772 for (j = 0; j < strlen(opt_arg); j++) {
773 switch (opt_arg[j]) {
775 showdisassemble = true;
779 showconstantpool = true;
782 showddatasegment = true;
785 showintermediate = true;
786 compileverbose = true;
806 for (j = 0; j < strlen(opt_arg); j++) {
807 switch (opt_arg[j]) {
812 inlinevirtuals = true;
815 inlineexceptions = true;
818 inlineparamopt = true;
821 inlineoutsiders = true;
835 opt_xta = false; /**not yet **/
839 /***opt_vta = true; not yet **/
849 if (opt_ind >= argc) {
854 mainstring = argv[opt_ind++];
855 for (i = strlen(mainstring) - 1; i >= 0; i--) { /* Transform dots into slashes */
856 if (mainstring[i] == '.') mainstring[i] = '/'; /* in the class name */
860 /**************************** Program start *****************************/
862 log_init(logfilename);
864 log_text("CACAO started -------------------------------------------------------");
866 /* initialize the garbage collector */
867 gc_init(heapmaxsize, heapstartsize);
869 native_setclasspath(classpath);
872 suck_init(classpath);
874 cacao_initializing=true;
876 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
880 loader_init((u1 *) &dummy);
882 native_loadclasses();
886 #if defined(USE_THREADS)
887 initThreads((u1*) &dummy);
891 class_init(class_new(utf_new_char("java/lang/System"))); /*That's important, otherwise we get into trouble, if
892 the Runtime static initializer is called before (circular dependency. This is with classpath
893 0.09. Another important thing is, that this has to happen after initThreads!!!
896 cacao_initializing=false;
897 /************************* Start worker routines ********************/
900 methodinfo *mainmethod;
903 /* create, load and link the main class */
904 mainclass = class_new(utf_new_char(mainstring));
906 if (!class_load(mainclass))
907 throw_exception_exit();
909 if (!class_link(mainclass))
910 throw_exception_exit();
912 mainmethod = class_resolveclassmethod(mainclass,
913 utf_new_char("main"),
914 utf_new_char("([Ljava/lang/String;)V"),
918 /* problems with main method? */
919 /* if (*exceptionptr) */
920 /* throw_exception_exit(); */
922 /* there is no main method or it isn't static */
923 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
925 new_exception_message(string_java_lang_NoSuchMethodError,
927 throw_exception_exit();
930 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
931 for (i = opt_ind; i < argc; i++) {
932 a->data[i - opt_ind] =
933 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
936 #ifdef TYPEINFO_DEBUG_TEST
937 /* test the typeinfo system */
940 /*class_showmethods(currentThread->group->header.vftbl->class); */
942 *threadrootmethod = mainmethod;
946 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
948 /* exception occurred? */
950 throw_exception_exit();
952 #if defined(USE_THREADS)
953 #if defined(NATIVE_THREADS)
956 killThread(currentThread);
960 /* now exit the JavaVM */
965 /************* If requested, compile all methods ********************/
973 /* create all classes found in the classpath */
974 /* XXX currently only works with zip/jar's */
975 create_all_classes();
977 /* load and link all classes */
978 for (slot = 0; slot < class_hash.size; slot++) {
979 c = class_hash.ptr[slot];
988 /* compile all class methods */
989 for (i = 0; i < c->methodscount; i++) {
990 m = &(c->methods[i]);
992 (void) jit_compile(m);
1002 /******** If requested, compile a specific method ***************/
1004 if (specificmethodname) {
1007 /* create, load and link the main class */
1008 mainclass = class_new(utf_new_char(mainstring));
1009 class_load(mainclass);
1012 throw_exception_exit();
1014 class_link(mainclass);
1017 throw_exception_exit();
1019 if (specificsignature) {
1020 m = class_resolveclassmethod(mainclass,
1021 utf_new_char(specificmethodname),
1022 utf_new_char(specificsignature),
1026 m = class_resolveclassmethod(mainclass,
1027 utf_new_char(specificmethodname),
1034 char message[MAXLOGTEXT];
1035 sprintf(message, "%s%s", specificmethodname,
1036 specificmethodname ? specificmethodname : "");
1039 new_exception_message(string_java_lang_NoSuchMethodException,
1042 throw_exception_exit();
1050 /* keep compiler happy */
1056 /* cacao_exit ******************************************************************
1058 Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
1060 *******************************************************************************/
1062 void cacao_exit(s4 status)
1066 java_lang_Runtime *rt;
1068 /* class should already be loaded, but who knows... */
1070 c = class_new(utf_new_char("java/lang/Runtime"));
1073 throw_exception_exit();
1076 throw_exception_exit();
1078 /* first call Runtime.getRuntime()Ljava.lang.Runtime; */
1080 m = class_resolveclassmethod(c,
1081 utf_new_char("getRuntime"),
1082 utf_new_char("()Ljava/lang/Runtime;"),
1083 class_java_lang_Object,
1087 throw_exception_exit();
1089 rt = (java_lang_Runtime *) asm_calljavafunction(m,
1095 /* exception occurred? */
1098 throw_exception_exit();
1100 /* then call Runtime.exit(I)V */
1102 m = class_resolveclassmethod(c,
1103 utf_new_char("exit"),
1104 utf_new_char("(I)V"),
1105 class_java_lang_Object,
1109 throw_exception_exit();
1111 asm_calljavafunction(m, rt, (void *) 0, NULL, NULL);
1113 /* this should never happen */
1115 throw_cacao_exception_exit(string_java_lang_InternalError,
1116 "Problems with Runtime.exit(I)V");
1120 /*************************** Shutdown function *********************************
1122 Terminates the system immediately without freeing memory explicitly (to be
1123 used only for abnormal termination)
1125 *******************************************************************************/
1127 void cacao_shutdown(s4 status)
1131 if (verbose || getcompilingtime || opt_stat) {
1132 log_text("CACAO terminated by shutdown");
1135 if (getcompilingtime)
1138 dolog("Exit status: %d\n", (int) status);
1146 * These are local overrides for various environment variables in Emacs.
1147 * Please do not remove this and leave it at the end of the file, where
1148 * Emacs will automagically detect them.
1149 * ---------------------------------------------------------------------
1152 * indent-tabs-mode: t