* src/vm/vm.c (opts): Added OPT_EA, OPT_DA.
[cacao.git] / src / vm / vm.c
1 /* src/vm/vm.c - VM startup and shutdown functions
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: vm.c 8066 2007-06-12 09:08:12Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <errno.h>
34 #include <stdlib.h>
35
36 #if defined(WITH_JRE_LAYOUT)
37 # include <libgen.h>
38 # include <unistd.h>
39 #endif
40
41 #include "vm/types.h"
42
43 #include "mm/gc-common.h"
44 #include "mm/memory.h"
45
46 #include "native/jni.h"
47 #include "native/native.h"
48 #include "native/include/java_lang_String.h" /* required by java_lang_Class.h */
49 #include "native/include/java_lang_Class.h"
50
51 #include "threads/threads-common.h"
52
53 #include "toolbox/logging.h"
54
55 #include "vm/builtin.h"
56 #include "vm/exceptions.h"
57 #include "vm/finalizer.h"
58 #include "vm/global.h"
59 #include "vm/initialize.h"
60 #include "vm/properties.h"
61 #include "vm/signallocal.h"
62 #include "vm/stringlocal.h"
63 #include "vm/vm.h"
64
65 #include "vm/jit/jit.h"
66 #include "vm/jit/md.h"
67 #include "vm/jit/asmpart.h"
68
69 #if defined(ENABLE_PROFILING)
70 # include "vm/jit/optimizing/profile.h"
71 #endif
72
73 #include "vm/jit/optimizing/recompile.h"
74
75 #include "vmcore/classcache.h"
76 #include "vmcore/options.h"
77 #include "vmcore/primitive.h"
78 #include "vmcore/statistics.h"
79 #include "vmcore/suck.h"
80
81 #if defined(ENABLE_JVMTI)
82 # include "native/jvmti/cacaodbg.h"
83 #endif
84
85 #if defined(ENABLE_VMLOG)
86 #include <vmlog_cacao.h>
87 #endif
88
89
90 /* Invocation API variables ***************************************************/
91
92 _Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
93 _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
94
95
96 /* global variables ***********************************************************/
97
98 s4 vms = 0;                             /* number of VMs created              */
99
100 bool vm_initializing = false;
101 bool vm_exiting = false;
102
103 char      *cacao_prefix = NULL;
104 char      *cacao_libjvm = NULL;
105 char      *classpath_libdir = NULL;
106
107 char      *_Jv_bootclasspath;           /* contains the boot classpath        */
108 char      *_Jv_classpath;               /* contains the classpath             */
109 char      *_Jv_java_library_path;
110
111 char      *mainstring = NULL;
112 classinfo *mainclass = NULL;
113
114 char *specificmethodname = NULL;
115 char *specificsignature = NULL;
116
117 bool startit = true;
118
119 #if defined(ENABLE_INTRP)
120 u1 *intrp_main_stack = NULL;
121 #endif
122
123
124 /* define heap sizes **********************************************************/
125
126 #define HEAP_MAXSIZE      128 * 1024 * 1024 /* default 128MB                  */
127 #define HEAP_STARTSIZE      2 * 1024 * 1024 /* default 2MB                    */
128 #define STACK_SIZE                64 * 1024 /* default 64kB                   */
129
130
131 /* define command line options ************************************************/
132
133 enum {
134         OPT_FOO,
135
136         /* Java options */
137
138         OPT_JAR,
139
140         OPT_D32,
141         OPT_D64,
142
143         OPT_CLASSPATH,
144         OPT_D,
145
146         OPT_VERBOSE,
147
148         OPT_VERSION,
149         OPT_SHOWVERSION,
150         OPT_FULLVERSION,
151
152         OPT_HELP,
153         OPT_X,
154         OPT_XX,
155
156         OPT_EA,
157         OPT_DA,
158
159         OPT_ESA,
160         OPT_DSA,
161
162         /* Java non-standard options */
163
164         OPT_JIT,
165         OPT_INTRP,
166
167         OPT_BOOTCLASSPATH,
168         OPT_BOOTCLASSPATH_A,
169         OPT_BOOTCLASSPATH_P,
170
171         OPT_BOOTCLASSPATH_C,
172
173 #if defined(ENABLE_PROFILING)
174         OPT_PROF,
175         OPT_PROF_OPTION,
176 #endif
177
178         OPT_MS,
179         OPT_MX,
180
181         /* CACAO options */
182
183         OPT_VERBOSE1,
184         OPT_NOIEEE,
185
186 #if defined(ENABLE_STATISTICS)
187         OPT_TIME,
188         OPT_STAT,
189 #endif
190
191         OPT_LOG,
192         OPT_CHECK,
193         OPT_LOAD,
194         OPT_SHOW,
195         OPT_DEBUGCOLOR,
196
197 #if !defined(NDEBUG)
198         OPT_ALL,
199         OPT_METHOD,
200         OPT_SIGNATURE,
201 #endif
202
203 #if defined(ENABLE_VERIFIER)
204         OPT_NOVERIFY,
205 #if defined(TYPECHECK_VERBOSE)
206         OPT_VERBOSETC,
207 #endif
208 #endif /* defined(ENABLE_VERIFIER) */
209         OPT_EAGER,
210
211         /* optimization options */
212
213 #if defined(ENABLE_LOOP)
214         OPT_OLOOP,
215 #endif
216         
217 #if defined(ENABLE_IFCONV)
218         OPT_IFCONV,
219 #endif
220
221 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
222         OPT_LSRA,
223 #endif
224
225 #if defined(ENABLE_INLINING)
226         OPT_INLINING,
227 #if !defined(NDEBUG)
228         OPT_INLINE_LOG,
229 #endif
230 #if defined(ENABLE_INLINING_DEBUG)
231         OPT_INLINE_DEBUG_ALL,
232         OPT_INLINE_DEBUG_END,
233         OPT_INLINE_DEBUG_MIN,
234         OPT_INLINE_DEBUG_MAX,
235         OPT_INLINE_REPLACE_VERBOSE,
236         OPT_INLINE_REPLACE_VERBOSE2,
237 #endif /* defined(ENABLE_INLINING_DEBUG) */
238 #endif /* defined(ENABLE_INLINING) */
239
240 #if defined(ENABLE_INTRP)
241         /* interpreter options */
242
243         OPT_NO_DYNAMIC,
244         OPT_NO_REPLICATION,
245         OPT_NO_QUICKSUPER,
246         OPT_STATIC_SUPERS,
247         OPT_TRACE,
248 #endif
249
250         OPT_SS,
251
252 #ifdef ENABLE_JVMTI
253         OPT_DEBUG,
254         OPT_XRUNJDWP,
255         OPT_NOAGENT,
256         OPT_AGENTLIB,
257         OPT_AGENTPATH,
258 #endif
259
260 #if defined(ENABLE_DEBUG_FILTER)
261         OPT_FILTER_VERBOSECALL_INCLUDE,
262         OPT_FILTER_VERBOSECALL_EXCLUDE,
263         OPT_FILTER_SHOW_METHOD,
264 #endif
265
266         DUMMY
267 };
268
269
270 opt_struct opts[] = {
271         { "foo",               false, OPT_FOO },
272
273         /* Java options */
274
275         { "jar",               false, OPT_JAR },
276
277         { "d32",               false, OPT_D32 },
278         { "d64",               false, OPT_D64 },
279         { "client",            false, OPT_IGNORE },
280         { "server",            false, OPT_IGNORE },
281         { "jvm",               false, OPT_IGNORE },
282         { "hotspot",           false, OPT_IGNORE },
283
284         { "classpath",         true,  OPT_CLASSPATH },
285         { "cp",                true,  OPT_CLASSPATH },
286         { "D",                 true,  OPT_D },
287         { "version",           false, OPT_VERSION },
288         { "showversion",       false, OPT_SHOWVERSION },
289         { "fullversion",       false, OPT_FULLVERSION },
290         { "help",              false, OPT_HELP },
291         { "?",                 false, OPT_HELP },
292         { "X",                 false, OPT_X },
293         { "XX:",               true,  OPT_XX },
294
295         { "ea:",               true,  OPT_EA },
296         { "da:",               true,  OPT_DA },
297         { "ea",                false, OPT_EA },
298         { "da",                false, OPT_DA },
299
300         { "esa",                     false, OPT_ESA },
301         { "enablesystemassertions",  false, OPT_ESA },
302         { "dsa",                     false, OPT_DSA },
303         { "disablesystemassertions", false, OPT_DSA },
304
305         { "noasyncgc",         false, OPT_IGNORE },
306 #if defined(ENABLE_VERIFIER)
307         { "noverify",          false, OPT_NOVERIFY },
308 #endif
309         { "v",                 false, OPT_VERBOSE1 },
310         { "verbose:",          true,  OPT_VERBOSE },
311
312 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
313         { "verbosetc",         false, OPT_VERBOSETC },
314 #endif
315 #if defined(__ALPHA__)
316         { "noieee",            false, OPT_NOIEEE },
317 #endif
318 #if defined(ENABLE_STATISTICS)
319         { "time",              false, OPT_TIME },
320         { "stat",              false, OPT_STAT },
321 #endif
322         { "log",               true,  OPT_LOG },
323         { "c",                 true,  OPT_CHECK },
324         { "l",                 false, OPT_LOAD },
325         { "eager",             false, OPT_EAGER },
326
327 #if !defined(NDEBUG)
328         { "all",               false, OPT_ALL },
329         { "sig",               true,  OPT_SIGNATURE },
330 #endif
331
332 #if defined(ENABLE_LOOP)
333         { "oloop",             false, OPT_OLOOP },
334 #endif
335 #if defined(ENABLE_IFCONV)
336         { "ifconv",            false, OPT_IFCONV },
337 #endif
338 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
339         { "lsra",              false, OPT_LSRA },
340 #endif
341
342 #if defined(ENABLE_INTRP)
343         /* interpreter options */
344
345         { "trace",             false, OPT_TRACE },
346         { "static-supers",     true,  OPT_STATIC_SUPERS },
347         { "no-dynamic",        false, OPT_NO_DYNAMIC },
348         { "no-replication",    false, OPT_NO_REPLICATION },
349         { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
350 #endif
351
352         /* JVMTI Agent Command Line Options */
353 #ifdef ENABLE_JVMTI
354         { "agentlib:",         true,  OPT_AGENTLIB },
355         { "agentpath:",        true,  OPT_AGENTPATH },
356 #endif
357
358         /* Java non-standard options */
359
360         { "Xjit",              false, OPT_JIT },
361         { "Xint",              false, OPT_INTRP },
362         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
363         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
364         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
365         { "Xbootclasspath/c:", true,  OPT_BOOTCLASSPATH_C },
366
367 #ifdef ENABLE_JVMTI
368         { "Xdebug",            false, OPT_DEBUG },
369         { "Xnoagent",          false, OPT_NOAGENT },
370         { "Xrunjdwp",          true,  OPT_XRUNJDWP },
371 #endif 
372
373         { "Xms",               true,  OPT_MS },
374         { "ms",                true,  OPT_MS },
375         { "Xmx",               true,  OPT_MX },
376         { "mx",                true,  OPT_MX },
377         { "Xss",               true,  OPT_SS },
378         { "ss",                true,  OPT_SS },
379
380 #if defined(ENABLE_PROFILING)
381         { "Xprof:",            true,  OPT_PROF_OPTION },
382         { "Xprof",             false, OPT_PROF },
383 #endif
384
385         /* inlining options */
386
387 #if defined(ENABLE_INLINING)
388 #if defined(ENABLE_INLINING_DEBUG)
389         { "ia",                false, OPT_INLINE_DEBUG_ALL },
390         { "ii",                true,  OPT_INLINE_DEBUG_MIN },
391         { "im",                true,  OPT_INLINE_DEBUG_MAX },
392         { "ie",                true,  OPT_INLINE_DEBUG_END },
393         { "ir",                false, OPT_INLINE_REPLACE_VERBOSE },
394         { "iR",                false, OPT_INLINE_REPLACE_VERBOSE2 },
395 #endif /* defined(ENABLE_INLINING_DEBUG) */
396 #if !defined(NDEBUG)
397         { "il",                false, OPT_INLINE_LOG },
398 #endif
399         { "i",                 false, OPT_INLINING },
400 #endif /* defined(ENABLE_INLINING) */
401
402         /* keep these at the end of the list */
403
404 #if !defined(NDEBUG)
405         { "m",                 true,  OPT_METHOD },
406 #endif
407
408         { "s",                 true,  OPT_SHOW },
409         { "debug-color",      false,  OPT_DEBUGCOLOR },
410
411 #if defined(ENABLE_DEBUG_FILTER)
412         { "XXfi",              true,  OPT_FILTER_VERBOSECALL_INCLUDE },
413         { "XXfx",              true,  OPT_FILTER_VERBOSECALL_EXCLUDE },
414         { "XXfm",              true,  OPT_FILTER_SHOW_METHOD },
415 #endif
416
417         { NULL,                false, 0 }
418 };
419
420
421 /* usage ***********************************************************************
422
423    Prints the correct usage syntax to stdout.
424
425 *******************************************************************************/
426
427 void usage(void)
428 {
429         puts("Usage: cacao [-options] classname [arguments]");
430         puts("               (to run a class file)");
431         puts("   or  cacao [-options] -jar jarfile [arguments]");
432         puts("               (to run a standalone jar file)\n");
433
434         puts("where options include:");
435         puts("    -d32                     use 32-bit data model if available");
436         puts("    -d64                     use 64-bit data model if available");
437         puts("    -client                  compatibility (currently ignored)");
438         puts("    -server                  compatibility (currently ignored)");
439         puts("    -jvm                     compatibility (currently ignored)");
440         puts("    -hotspot                 compatibility (currently ignored)\n");
441
442         puts("    -cp <path>               specify a path to look for classes");
443         puts("    -classpath <path>        specify a path to look for classes");
444         puts("    -D<name>=<value>         add an entry to the property list");
445         puts("    -verbose[:class|gc|jni]  enable specific verbose output");
446         puts("    -version                 print product version and exit");
447         puts("    -fullversion             print jpackage-compatible product version and exit");
448         puts("    -showversion             print product version and continue");
449         puts("    -help, -?                print this help message");
450         puts("    -X                       print help on non-standard Java options");
451         puts("    -XX                      print help on CACAO options");
452     puts("    -ea[:<packagename>...|:<classname>]");
453     puts("    -enableassertions[:<packagename>...|:<classname>]");
454         puts("                             enable assertions with specified granularity");
455         puts("    -da[:<packagename>...|:<classname>]");
456         puts("    -disableassertions[:<packagename>...|:<classname>]");
457         puts("                             disable assertions with specified granularity");
458         puts("    -esa | -enablesystemassertions");
459         puts("                             enable system assertions");
460         puts("    -dsa | -disablesystemassertions");
461         puts("                             disable system assertions");
462
463 #ifdef ENABLE_JVMTI
464         puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
465         puts ("                                         for jdwp help use: -agentlib:jdwp=help");
466         puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
467 #endif
468
469         /* exit with error code */
470
471         exit(1);
472 }   
473
474
475 static void Xusage(void)
476 {
477 #if defined(ENABLE_JIT)
478         puts("    -Xjit                    JIT mode execution (default)");
479 #endif
480 #if defined(ENABLE_INTRP)
481         puts("    -Xint                    interpreter mode execution");
482 #endif
483         puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
484     puts("                             value is set as bootstrap class path");
485         puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
486         puts("                             value is appended to the bootstrap class path");
487         puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
488         puts("                             value is prepended to the bootstrap class path");
489         puts("    -Xbootclasspath/c:<zip/jar files and directories separated by :>");
490         puts("                             value is used as Java core library, but the");
491         puts("                             hardcoded VM interface classes are prepended");
492         printf("    -Xms<size>               set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
493         printf("    -Xmx<size>               set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
494         printf("    -Xss<size>               set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
495
496 #if defined(ENABLE_PROFILING)
497         puts("    -Xprof[:bb]              collect and print profiling data");
498 #endif
499
500 #if defined(ENABLE_JVMTI)
501     /* -Xdebug option depend on gnu classpath JDWP options. options: 
502          transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
503         puts("    -Xdebug                  enable remote debugging\n");
504         puts("    -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
505         puts("                             enable remote debugging\n");
506 #endif 
507
508         /* exit with error code */
509
510         exit(1);
511 }   
512
513
514 static void XXusage(void)
515 {
516         puts("    -v                       write state-information");
517 #if !defined(NDEBUG)
518         puts("    -verbose[:call|exception|jit|memory|threads]");
519         puts("                             enable specific verbose output");
520         puts("    -debug-color             colored output for ANSI terms");
521 #endif
522 #ifdef TYPECHECK_VERBOSE
523         puts("    -verbosetc               write debug messages while typechecking");
524 #endif
525 #if defined(__ALPHA__)
526         puts("    -noieee                  don't use ieee compliant arithmetic");
527 #endif
528 #if defined(ENABLE_VERIFIER)
529         puts("    -noverify                don't verify classfiles");
530 #endif
531 #if defined(ENABLE_STATISTICS)
532         puts("    -time                    measure the runtime");
533         puts("    -stat                    detailed compiler statistics");
534 #endif
535         puts("    -log logfile             specify a name for the logfile");
536         puts("    -c(heck)b(ounds)         don't check array bounds");
537         puts("            s(ync)           don't check for synchronization");
538 #if defined(ENABLE_LOOP)
539         puts("    -oloop                   optimize array accesses in loops");
540 #endif
541         puts("    -l                       don't start the class after loading");
542         puts("    -eager                   perform eager class loading and linking");
543 #if !defined(NDEBUG)
544         puts("    -all                     compile all methods, no execution");
545         puts("    -m                       compile only a specific method");
546         puts("    -sig                     specify signature for a specific method");
547 #endif
548
549         puts("    -s...                    show...");
550         puts("      (c)onstants            the constant pool");
551         puts("      (m)ethods              class fields and methods");
552         puts("      (u)tf                  the utf - hash");
553         puts("      (i)ntermediate         intermediate representation");
554 #if defined(ENABLE_DISASSEMBLER)
555         puts("      (a)ssembler            disassembled listing");
556         puts("      n(o)ps                 show NOPs in disassembler output");
557         puts("      (e)xceptionstubs       disassembled exception stubs (only with -sa)");
558         puts("      (n)ative               disassembled native stubs");
559 #endif
560         puts("      (d)atasegment          data segment listing");
561
562 #if defined(ENABLE_INLINING)
563         puts("    -i                       activate inlining");
564 #if !defined(NDEBUG)
565         puts("    -il                      log inlining");
566 #endif
567 #if defined(ENABLE_INLINING_DEBUG)
568         puts("    -ia                      use inlining for all methods");
569         puts("    -ii <size>               set minimum size for inlined result");
570         puts("    -im <size>               set maximum size for inlined result");
571         puts("    -ie <number>             stop inlining after the given number of roots");
572         puts("    -ir                      log on-stack replacement");
573         puts("    -iR                      log on-stack replacement, more verbose");
574 #endif /* defined(ENABLE_INLINING_DEBUG) */
575 #endif /* defined(ENABLE_INLINING) */
576
577 #if defined(ENABLE_IFCONV)
578         puts("    -ifconv                  use if-conversion");
579 #endif
580 #if defined(ENABLE_LSRA)
581         puts("    -lsra                    use linear scan register allocation");
582 #endif
583 #if defined(ENABLE_SSA)
584         puts("    -lsra                    use linear scan register allocation (with SSA)");
585 #endif
586 #if defined(ENABLE_DEBUG_FILTER)
587         puts("    -XXfi <regex>            begin of dynamic scope for verbosecall filter");
588         puts("    -XXfx <regex>            end of dynamic scope for verbosecall filter");
589         puts("    -XXfm <regex>            filter for show options");
590 #endif
591         /* exit with error code */
592
593         exit(1);
594 }
595
596
597 /* version *********************************************************************
598
599    Only prints cacao version information.
600
601 *******************************************************************************/
602
603 static void version(bool opt_exit)
604 {
605         puts("java version \""JAVA_VERSION"\"");
606         puts("CACAO version "VERSION"");
607
608         puts("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,");
609         puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
610         puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
611         puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
612
613         puts("This program is free software; you can redistribute it and/or");
614         puts("modify it under the terms of the GNU General Public License as");
615         puts("published by the Free Software Foundation; either version 2, or (at");
616         puts("your option) any later version.\n");
617
618         puts("This program is distributed in the hope that it will be useful, but");
619         puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
620         puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU");
621         puts("General Public License for more details.\n");
622
623         puts("Configure/Build options:\n");
624         puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
625 #if defined(__VERSION__)
626         puts("  CC         : "VERSION_CC" ("__VERSION__")");
627 #else
628         puts("  CC         : "VERSION_CC"");
629 #endif
630         puts("  CFLAGS     : "VERSION_CFLAGS"\n");
631
632         puts("Default variables:\n");
633         printf("  maximum heap size              : %d\n", HEAP_MAXSIZE);
634         printf("  initial heap size              : %d\n", HEAP_STARTSIZE);
635         printf("  stack size                     : %d\n", STACK_SIZE);
636 #if defined(WITH_CLASSPATH_GNU)
637         puts("  java.boot.class.path           : "CACAO_VM_ZIP":"CLASSPATH_CLASSES"");
638 #else
639         puts("  java.boot.class.path           : "CLASSPATH_CLASSES"");
640 #endif
641         puts("  gnu.classpath.boot.library.path: "CLASSPATH_LIBDIR"/classpath\n");
642
643         puts("Runtime variables:\n");
644         printf("  maximum heap size              : %d\n", opt_heapmaxsize);
645         printf("  initial heap size              : %d\n", opt_heapstartsize);
646         printf("  stack size                     : %d\n", opt_stacksize);
647         printf("  libjvm.so                      : %s\n", cacao_libjvm);
648         printf("  java.boot.class.path           : %s\n", _Jv_bootclasspath);
649         printf("  gnu.classpath.boot.library.path: %s\n", classpath_libdir);
650         printf("  java.class.path                : %s\n", _Jv_classpath);
651
652         /* exit normally, if requested */
653
654         if (opt_exit)
655                 exit(0);
656 }
657
658
659 /* fullversion *****************************************************************
660
661    Prints a Sun compatible version information (required e.g. by
662    jpackage, www.jpackage.org).
663
664 *******************************************************************************/
665
666 static void fullversion(void)
667 {
668         puts("java full version \"cacao-"JAVA_VERSION"\"");
669
670         /* exit normally */
671
672         exit(0);
673 }
674
675
676 /* forward declarations *******************************************************/
677
678 static char *vm_get_mainclass_from_jar(char *mainstring);
679 #if !defined(NDEBUG)
680 static void  vm_compile_all(void);
681 static void  vm_compile_method(void);
682 #endif
683
684
685 /* vm_createjvm ****************************************************************
686
687    Implementation for JNI_CreateJavaVM.
688
689 *******************************************************************************/
690
691 bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args)
692 {
693         JavaVMInitArgs *_vm_args;
694         _Jv_JNIEnv     *env;
695         _Jv_JavaVM     *vm;
696
697         /* get the arguments for the new JVM */
698
699         _vm_args = (JavaVMInitArgs *) vm_args;
700
701         /* get the VM and Env tables (must be set before vm_create) */
702
703         env = NEW(_Jv_JNIEnv);
704
705 #if defined(ENABLE_JNI)
706         env->env = &_Jv_JNINativeInterface;
707 #endif
708
709         /* XXX Set the global variable.  Maybe we should do that differently. */
710
711         _Jv_env = env;
712
713         /* create and fill a JavaVM structure */
714
715         vm = NEW(_Jv_JavaVM);
716
717 #if defined(ENABLE_JNI)
718         vm->functions = &_Jv_JNIInvokeInterface;
719 #endif
720
721         /* XXX Set the global variable.  Maybe we should do that differently. */
722         /* XXX JVMTI Agents needs a JavaVM  */
723
724         _Jv_jvm = vm;
725
726         /* actually create the JVM */
727
728         if (!vm_create(_vm_args))
729                 goto error;
730
731 #if defined(ENABLE_JNI)
732         /* setup the local ref table (must be created after vm_create) */
733
734         if (!jni_init_localref_table())
735                 goto error;
736 #endif
737
738         /* now return the values */
739
740         *p_vm  = (JavaVM *) vm;
741         *p_env = (void *) env;
742
743         return true;
744
745  error:
746         /* release allocated memory */
747
748         FREE(env, _Jv_JNIEnv);
749         FREE(vm, _Jv_JavaVM);
750
751         return false;
752 }
753
754
755 /* vm_create *******************************************************************
756
757    Creates a JVM.  Called by vm_createjvm.
758
759 *******************************************************************************/
760
761 bool vm_create(JavaVMInitArgs *vm_args)
762 {
763         char *cp;
764         s4    len;
765         s4    opt;
766         s4    i, j;
767         bool  opt_version;
768         bool  opt_exit;
769
770 #if defined(ENABLE_JVMTI)
771         lt_dlhandle  handle;
772         char *libname, *agentarg;
773         bool jdwp,agentbypath;
774         jdwp = agentbypath = false;
775 #endif
776
777 #if defined(ENABLE_VMLOG)
778         vmlog_cacao_init(vm_args);
779 #endif
780
781         /* check the JNI version requested */
782
783         switch (vm_args->version) {
784         case JNI_VERSION_1_1:
785                 break;
786         case JNI_VERSION_1_2:
787         case JNI_VERSION_1_4:
788                 break;
789         default:
790                 return false;
791         }
792
793         /* we only support 1 JVM instance */
794
795         if (vms > 0)
796                 return false;
797
798         if (atexit(vm_exit_handler))
799                 vm_abort("atexit failed: %s\n", strerror(errno));
800
801         if (opt_verbose)
802                 log_text("CACAO started -------------------------------------------------------");
803
804         /* We need to check if the actual size of a java.lang.Class object
805            is smaller or equal than the assumption made in
806            src/vmcore/class.h. */
807
808         if (sizeof(java_lang_Class) > sizeof(dummy_java_lang_Class))
809                 vm_abort("vm_create: java_lang_Class structure is bigger than classinfo.object (%d > %d)", sizeof(java_lang_Class), sizeof(dummy_java_lang_Class));
810
811         /* set the VM starttime */
812
813         _Jv_jvm->starttime = builtin_currenttimemillis();
814
815         /* get stuff from the environment *****************************************/
816
817 #if defined(WITH_JRE_LAYOUT)
818         /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
819
820         cacao_prefix = MNEW(char, 4096);
821
822         if (readlink("/proc/self/exe", cacao_prefix, 4095) == -1)
823                 vm_abort("readlink failed: %s\n", strerror(errno));
824
825         /* get the path of the current executable */
826
827         cacao_prefix = dirname(cacao_prefix);
828
829         if ((strlen(cacao_prefix) + strlen("/..") + strlen("0")) > 4096)
830                 vm_abort("libjvm name to long for buffer\n");
831
832         /* concatenate the library name */
833
834         strcat(cacao_prefix, "/..");
835
836         /* now set path to libjvm.so */
837
838         len = strlen(cacao_prefix) + strlen("/lib/libjvm") + strlen("0");
839
840         cacao_libjvm = MNEW(char, len);
841         strcpy(cacao_libjvm, cacao_prefix);
842         strcat(cacao_libjvm, "/lib/libjvm");
843
844         /* and finally set the path to GNU Classpath libraries */
845
846         len = strlen(cacao_prefix) + strlen("/lib/classpath") + strlen("0");
847
848         classpath_libdir = MNEW(char, len);
849         strcpy(classpath_libdir, cacao_prefix);
850         strcat(classpath_libdir, "/lib/classpath");
851 #else
852         cacao_prefix     = CACAO_PREFIX;
853         cacao_libjvm     = CACAO_LIBDIR"/libjvm";
854         classpath_libdir = CLASSPATH_LIBDIR"/classpath";
855 #endif
856
857         /* set the bootclasspath */
858
859         cp = getenv("BOOTCLASSPATH");
860
861         if (cp != NULL) {
862                 _Jv_bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
863                 strcpy(_Jv_bootclasspath, cp);
864         }
865         else {
866 #if defined(WITH_JRE_LAYOUT)
867                 len =
868 # if defined(WITH_CLASSPATH_GNU)
869                         strlen(cacao_prefix) +
870                         strlen("/share/cacao/vm.zip") +
871                         strlen(":") +
872 # endif
873                         strlen(cacao_prefix) +
874                         strlen("/share/classpath/glibj.zip") +
875                         strlen("0");
876
877                 _Jv_bootclasspath = MNEW(char, len);
878 # if defined(WITH_CLASSPATH_GNU)
879                 strcat(_Jv_bootclasspath, cacao_prefix);
880                 strcat(_Jv_bootclasspath, "/share/cacao/vm.zip");
881                 strcat(_Jv_bootclasspath, ":");
882 # endif
883                 strcat(_Jv_bootclasspath, cacao_prefix);
884                 strcat(_Jv_bootclasspath, "/share/classpath/glibj.zip");
885 #else
886                 len =
887 # if defined(WITH_CLASSPATH_GNU)
888                         strlen(CACAO_VM_ZIP) +
889                         strlen(":") +
890 # endif
891                         strlen(CLASSPATH_CLASSES) +
892                         strlen("0");
893
894                 _Jv_bootclasspath = MNEW(char, len);
895 # if defined(WITH_CLASSPATH_GNU)
896                 strcat(_Jv_bootclasspath, CACAO_VM_ZIP);
897                 strcat(_Jv_bootclasspath, ":");
898 # endif
899                 strcat(_Jv_bootclasspath, CLASSPATH_CLASSES);
900 #endif
901         }
902
903         /* set the classpath */
904
905         cp = getenv("CLASSPATH");
906
907         if (cp != NULL) {
908                 _Jv_classpath = MNEW(char, strlen(cp) + strlen("0"));
909                 strcat(_Jv_classpath, cp);
910         }
911         else {
912                 _Jv_classpath = MNEW(char, strlen(".") + strlen("0"));
913                 strcpy(_Jv_classpath, ".");
914         }
915
916         /* get and set java.library.path */
917
918         _Jv_java_library_path = getenv("LD_LIBRARY_PATH");
919
920         if (_Jv_java_library_path == NULL)
921                 _Jv_java_library_path = "";
922
923         /* interpret the options **************************************************/
924
925         opt_version       = false;
926         opt_exit          = false;
927
928         opt_noieee        = false;
929
930         opt_heapmaxsize   = HEAP_MAXSIZE;
931         opt_heapstartsize = HEAP_STARTSIZE;
932         opt_stacksize     = STACK_SIZE;
933
934
935 #if defined(ENABLE_JVMTI)
936         /* initialize JVMTI related  **********************************************/
937         jvmti = false;
938 #endif
939
940         /* initialize and fill properties before command-line handling */
941
942         if (!properties_init())
943                 vm_abort("properties_init failed");
944
945         /* iterate over all passed options */
946
947         while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
948                 switch (opt) {
949                 case OPT_FOO:
950                         opt_foo = true;
951                         break;
952
953                 case OPT_IGNORE:
954                         break;
955                         
956                 case OPT_JAR:
957                         opt_jar = true;
958                         break;
959
960                 case OPT_D32:
961 #if SIZEOF_VOID_P == 8
962                         puts("Running a 32-bit JVM is not supported on this platform.");
963                         exit(1);
964 #endif
965                         break;
966
967                 case OPT_D64:
968 #if SIZEOF_VOID_P == 4
969                         puts("Running a 64-bit JVM is not supported on this platform.");
970                         exit(1);
971 #endif
972                         break;
973
974                 case OPT_CLASSPATH:
975                         /* forget old classpath and set the argument as new classpath */
976                         MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
977
978                         _Jv_classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
979                         strcpy(_Jv_classpath, opt_arg);
980                         break;
981
982                 case OPT_D:
983                         for (i = 0; i < strlen(opt_arg); i++) {
984                                 if (opt_arg[i] == '=') {
985                                         opt_arg[i] = '\0';
986                                         properties_add(opt_arg, opt_arg + i + 1);
987                                         goto opt_d_done;
988                                 }
989                         }
990
991                         /* if no '=' is given, just create an empty property */
992
993                         properties_add(opt_arg, "");
994
995                 opt_d_done:
996                         break;
997
998                 case OPT_BOOTCLASSPATH:
999                         /* Forget default bootclasspath and set the argument as
1000                            new boot classpath. */
1001
1002                         MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
1003
1004                         _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
1005                         strcpy(_Jv_bootclasspath, opt_arg);
1006                         break;
1007
1008                 case OPT_BOOTCLASSPATH_A:
1009                         /* append to end of bootclasspath */
1010
1011                         len = strlen(_Jv_bootclasspath);
1012
1013                         _Jv_bootclasspath = MREALLOC(_Jv_bootclasspath,
1014                                                                                  char,
1015                                                                                  len + strlen("0"),
1016                                                                                  len + strlen(":") +
1017                                                                                  strlen(opt_arg) + strlen("0"));
1018
1019                         strcat(_Jv_bootclasspath, ":");
1020                         strcat(_Jv_bootclasspath, opt_arg);
1021                         break;
1022
1023                 case OPT_BOOTCLASSPATH_P:
1024                         /* prepend in front of bootclasspath */
1025
1026                         cp = _Jv_bootclasspath;
1027                         len = strlen(cp);
1028
1029                         _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
1030                                                                          len + strlen("0"));
1031
1032                         strcpy(_Jv_bootclasspath, opt_arg);
1033                         strcat(_Jv_bootclasspath, ":");
1034                         strcat(_Jv_bootclasspath, cp);
1035
1036                         MFREE(cp, char, len);
1037                         break;
1038
1039                 case OPT_BOOTCLASSPATH_C:
1040                         /* use as Java core library, but prepend VM interface classes */
1041
1042                         MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
1043
1044                         len = strlen(CACAO_VM_ZIP) +
1045                                 strlen(":") +
1046                                 strlen(opt_arg) +
1047                                 strlen("0");
1048
1049                         _Jv_bootclasspath = MNEW(char, len);
1050
1051                         strcpy(_Jv_bootclasspath, CACAO_VM_ZIP);
1052                         strcat(_Jv_bootclasspath, ":");
1053                         strcat(_Jv_bootclasspath, opt_arg);
1054                         break;
1055
1056 #if defined(ENABLE_JVMTI)
1057                 case OPT_DEBUG:
1058                         /* this option exists only for compatibility reasons */
1059                         break;
1060
1061                 case OPT_NOAGENT:
1062                         /* I don't know yet what Xnoagent should do. This is only for 
1063                            compatiblity with eclipse - motse */
1064                         break;
1065
1066                 case OPT_XRUNJDWP:
1067                         agentbypath = true;
1068                         jvmti       = true;
1069                         jdwp        = true;
1070
1071                         len =
1072                                 strlen(CACAO_LIBDIR) +
1073                                 strlen("/libjdwp.so=") +
1074                                 strlen(opt_arg) +
1075                                 strlen("0");
1076
1077                         agentarg = MNEW(char, len);
1078
1079                         strcpy(agentarg, CACAO_LIBDIR);
1080                         strcat(agentarg, "/libjdwp.so=");
1081                         strcat(agentarg, &opt_arg[1]);
1082                         break;
1083
1084                 case OPT_AGENTPATH:
1085                         agentbypath = true;
1086
1087                 case OPT_AGENTLIB:
1088                         jvmti = true;
1089                         agentarg = opt_arg;
1090                         break;
1091 #endif
1092                         
1093                 case OPT_MX:
1094                 case OPT_MS:
1095                 case OPT_SS:
1096                         {
1097                                 char c;
1098                                 c = opt_arg[strlen(opt_arg) - 1];
1099
1100                                 if ((c == 'k') || (c == 'K')) {
1101                                         j = atoi(opt_arg) * 1024;
1102
1103                                 } else if ((c == 'm') || (c == 'M')) {
1104                                         j = atoi(opt_arg) * 1024 * 1024;
1105
1106                                 } else
1107                                         j = atoi(opt_arg);
1108
1109                                 if (opt == OPT_MX)
1110                                         opt_heapmaxsize = j;
1111                                 else if (opt == OPT_MS)
1112                                         opt_heapstartsize = j;
1113                                 else
1114                                         opt_stacksize = j;
1115                         }
1116                         break;
1117
1118                 case OPT_VERBOSE1:
1119                         opt_verbose = true;
1120                         break;
1121
1122                 case OPT_VERBOSE:
1123                         if (strcmp("class", opt_arg) == 0) {
1124                                 opt_verboseclass = true;
1125                         }
1126                         else if (strcmp("gc", opt_arg) == 0) {
1127                                 opt_verbosegc = true;
1128                         }
1129                         else if (strcmp("jni", opt_arg) == 0) {
1130                                 opt_verbosejni = true;
1131                         }
1132 #if !defined(NDEBUG)
1133                         else if (strcmp("call", opt_arg) == 0) {
1134                                 opt_verbosecall = true;
1135                         }
1136                         else if (strcmp("exception", opt_arg) == 0) {
1137                                 opt_verboseexception = true;
1138                         }
1139                         else if (strcmp("jit", opt_arg) == 0) {
1140                                 opt_verbose = true;
1141                                 loadverbose = true;
1142                                 linkverbose = true;
1143                                 initverbose = true;
1144                                 compileverbose = true;
1145                         }
1146                         else if (strcmp("memory", opt_arg) == 0) {
1147                                 opt_verbosememory = true;
1148
1149 # if defined(ENABLE_STATISTICS)
1150                                 /* we also need statistics */
1151
1152                                 opt_stat = true;
1153 # endif
1154                         }
1155                         else if (strcmp("threads", opt_arg) == 0) {
1156                                 opt_verbosethreads = true;
1157                         }
1158 #endif
1159                         else {
1160                                 printf("Unknown -verbose option: %s\n", opt_arg);
1161                                 usage();
1162                         }
1163                         break;
1164
1165                 case OPT_DEBUGCOLOR:
1166                         opt_debugcolor = true;
1167                         break;
1168
1169 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
1170                 case OPT_VERBOSETC:
1171                         opt_typecheckverbose = true;
1172                         break;
1173 #endif
1174                                 
1175                 case OPT_VERSION:
1176                         opt_version = true;
1177                         opt_exit    = true;
1178                         break;
1179
1180                 case OPT_FULLVERSION:
1181                         fullversion();
1182                         break;
1183
1184                 case OPT_SHOWVERSION:
1185                         opt_version = true;
1186                         break;
1187
1188                 case OPT_NOIEEE:
1189                         opt_noieee = true;
1190                         break;
1191
1192 #if defined(ENABLE_VERIFIER)
1193                 case OPT_NOVERIFY:
1194                         opt_verify = false;
1195                         break;
1196 #endif
1197
1198 #if defined(ENABLE_STATISTICS)
1199                 case OPT_TIME:
1200                         opt_getcompilingtime = true;
1201                         opt_getloadingtime = true;
1202                         break;
1203                                         
1204                 case OPT_STAT:
1205                         opt_stat = true;
1206                         break;
1207 #endif
1208                                         
1209                 case OPT_LOG:
1210                         log_init(opt_arg);
1211                         break;
1212                         
1213                 case OPT_CHECK:
1214                         for (i = 0; i < strlen(opt_arg); i++) {
1215                                 switch (opt_arg[i]) {
1216                                 case 'b':
1217                                         checkbounds = false;
1218                                         break;
1219                                 case 's':
1220                                         checksync = false;
1221                                         break;
1222                                 default:
1223                                         usage();
1224                                 }
1225                         }
1226                         break;
1227                         
1228                 case OPT_LOAD:
1229                         opt_run = false;
1230                         makeinitializations = false;
1231                         break;
1232
1233                 case OPT_EAGER:
1234                         opt_eager = true;
1235                         break;
1236
1237 #if !defined(NDEBUG)
1238                 case OPT_ALL:
1239                         compileall = true;
1240                         opt_run = false;
1241                         makeinitializations = false;
1242                         break;
1243
1244                 case OPT_METHOD:
1245                         opt_run = false;
1246                         opt_method = opt_arg;
1247                         makeinitializations = false;
1248                         break;
1249
1250                 case OPT_SIGNATURE:
1251                         opt_signature = opt_arg;
1252                         break;
1253 #endif
1254
1255                 case OPT_SHOW:       /* Display options */
1256                         for (i = 0; i < strlen(opt_arg); i++) {         
1257                                 switch (opt_arg[i]) {
1258                                 case 'c':
1259                                         showconstantpool = true;
1260                                         break;
1261
1262                                 case 'u':
1263                                         showutf = true;
1264                                         break;
1265
1266                                 case 'm':
1267                                         showmethods = true;
1268                                         break;
1269
1270                                 case 'i':
1271                                         opt_showintermediate = true;
1272                                         compileverbose = true;
1273                                         break;
1274
1275 #if defined(ENABLE_DISASSEMBLER)
1276                                 case 'a':
1277                                         opt_showdisassemble = true;
1278                                         compileverbose = true;
1279                                         break;
1280
1281                                 case 'o':
1282                                         opt_shownops = true;
1283                                         break;
1284
1285                                 case 'e':
1286                                         opt_showexceptionstubs = true;
1287                                         break;
1288
1289                                 case 'n':
1290                                         opt_shownativestub = true;
1291                                         break;
1292 #endif
1293
1294                                 case 'd':
1295                                         opt_showddatasegment = true;
1296                                         break;
1297
1298                                 default:
1299                                         usage();
1300                                 }
1301                         }
1302                         break;
1303                         
1304 #if defined(ENABLE_LOOP)
1305                 case OPT_OLOOP:
1306                         opt_loops = true;
1307                         break;
1308 #endif
1309
1310 #if defined(ENABLE_INLINING)
1311 #if defined(ENABLE_INLINING_DEBUG)
1312                 case OPT_INLINE_DEBUG_ALL:
1313                         opt_inline_debug_all = true;
1314                         break;
1315                 case OPT_INLINE_DEBUG_END:
1316                         opt_inline_debug_end_counter = atoi(opt_arg);
1317                         break;
1318                 case OPT_INLINE_DEBUG_MIN:
1319                         opt_inline_debug_min_size = atoi(opt_arg);
1320                         break;
1321                 case OPT_INLINE_DEBUG_MAX:
1322                         opt_inline_debug_max_size = atoi(opt_arg);
1323                         break;
1324                 case OPT_INLINE_REPLACE_VERBOSE:
1325                         opt_replace_verbose = 1;
1326                         break;
1327                 case OPT_INLINE_REPLACE_VERBOSE2:
1328                         opt_replace_verbose = 2;
1329                         break;
1330 #endif /* defined(ENABLE_INLINING_DEBUG) */
1331 #if !defined(NDEBUG)
1332                 case OPT_INLINE_LOG:
1333                         opt_inline_debug_log = true;
1334                         break;
1335 #endif /* !defined(NDEBUG) */
1336
1337                 case OPT_INLINING:
1338                         opt_inlining = true;
1339                         break;
1340 #endif /* defined(ENABLE_INLINING) */
1341
1342 #if defined(ENABLE_IFCONV)
1343                 case OPT_IFCONV:
1344                         opt_ifconv = true;
1345                         break;
1346 #endif
1347
1348 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1349                 case OPT_LSRA:
1350                         opt_lsra = true;
1351                         break;
1352 #endif
1353
1354                 case OPT_HELP:
1355                         usage();
1356                         break;
1357
1358                 case OPT_X:
1359                         Xusage();
1360                         break;
1361
1362                 case OPT_XX:
1363                         options_xx(opt_arg);
1364                         break;
1365
1366                 case OPT_EA:
1367                         /* currently ignored */
1368                         break;
1369
1370                 case OPT_DA:
1371                         /* currently ignored */
1372                         break;
1373
1374                 case OPT_ESA:
1375                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true;
1376                         break;
1377
1378                 case OPT_DSA:
1379                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = false;
1380                         break;
1381
1382 #if defined(ENABLE_PROFILING)
1383                 case OPT_PROF_OPTION:
1384                         /* use <= to get the last \0 too */
1385
1386                         for (i = 0, j = 0; i <= strlen(opt_arg); i++) {
1387                                 if (opt_arg[i] == ',')
1388                                         opt_arg[i] = '\0';
1389
1390                                 if (opt_arg[i] == '\0') {
1391                                         if (strcmp("bb", opt_arg + j) == 0)
1392                                                 opt_prof_bb = true;
1393
1394                                         else {
1395                                                 printf("Unknown option: -Xprof:%s\n", opt_arg + j);
1396                                                 usage();
1397                                         }
1398
1399                                         /* set k to next char */
1400
1401                                         j = i + 1;
1402                                 }
1403                         }
1404                         /* fall through */
1405
1406                 case OPT_PROF:
1407                         opt_prof = true;
1408                         break;
1409 #endif
1410
1411                 case OPT_JIT:
1412 #if defined(ENABLE_JIT)
1413                         opt_jit = true;
1414 #else
1415                         printf("-Xjit option not enabled.\n");
1416                         exit(1);
1417 #endif
1418                         break;
1419
1420                 case OPT_INTRP:
1421 #if defined(ENABLE_INTRP)
1422                         opt_intrp = true;
1423 #else
1424                         printf("-Xint option not enabled.\n");
1425                         exit(1);
1426 #endif
1427                         break;
1428
1429 #if defined(ENABLE_INTRP)
1430                 case OPT_STATIC_SUPERS:
1431                         opt_static_supers = atoi(opt_arg);
1432                         break;
1433
1434                 case OPT_NO_DYNAMIC:
1435                         opt_no_dynamic = true;
1436                         break;
1437
1438                 case OPT_NO_REPLICATION:
1439                         opt_no_replication = true;
1440                         break;
1441
1442                 case OPT_NO_QUICKSUPER:
1443                         opt_no_quicksuper = true;
1444                         break;
1445
1446                 case OPT_TRACE:
1447                         vm_debug = true;
1448                         break;
1449 #endif
1450
1451 #if defined(ENABLE_DEBUG_FILTER)
1452                 case OPT_FILTER_VERBOSECALL_INCLUDE:
1453                         opt_filter_verbosecall_include = opt_arg;
1454                         break;
1455
1456                 case OPT_FILTER_VERBOSECALL_EXCLUDE:
1457                         opt_filter_verbosecall_exclude = opt_arg;
1458                         break;
1459
1460                 case OPT_FILTER_SHOW_METHOD:
1461                         opt_filter_show_method = opt_arg;
1462                         break;
1463
1464 #endif
1465                 default:
1466                         printf("Unknown option: %s\n",
1467                                    vm_args->options[opt_index].optionString);
1468                         usage();
1469                 }
1470         }
1471
1472         /* get the main class *****************************************************/
1473
1474         if (opt_index < vm_args->nOptions) {
1475                 mainstring = vm_args->options[opt_index++].optionString;
1476
1477                 /* Put the jar file into the classpath (if any). */
1478
1479                 if (opt_jar == true) {
1480                         /* free old classpath */
1481
1482                         MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
1483
1484                         /* put jarfile into classpath */
1485
1486                         _Jv_classpath = MNEW(char, strlen(mainstring) + strlen("0"));
1487
1488                         strcpy(_Jv_classpath, mainstring);
1489                 }
1490                 else {
1491                         /* replace .'s with /'s in classname */
1492
1493                         for (i = strlen(mainstring) - 1; i >= 0; i--)
1494                                 if (mainstring[i] == '.')
1495                                         mainstring[i] = '/';
1496                 }
1497         }
1498
1499 #if defined(ENABLE_JVMTI)
1500         if (jvmti) {
1501                 jvmti_set_phase(JVMTI_PHASE_ONLOAD);
1502                 jvmti_agentload(agentarg, agentbypath, &handle, &libname);
1503
1504                 if (jdwp)
1505                         MFREE(agentarg, char, strlen(agentarg));
1506
1507                 jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
1508         }
1509 #endif
1510
1511         /* initialize this JVM ****************************************************/
1512
1513         vm_initializing = true;
1514
1515 #if defined(ENABLE_THREADS)
1516         /* pre-initialize some core thread stuff, like the stopworldlock,
1517            thus this has to happen _before_ gc_init()!!! */
1518
1519         threads_preinit();
1520 #endif
1521
1522         /* initialize the garbage collector */
1523
1524         gc_init(opt_heapmaxsize, opt_heapstartsize);
1525
1526         /* install architecture dependent signal handlers */
1527
1528         if (!signal_init())
1529                 vm_abort("vm_create: signal_init failed");
1530
1531 #if defined(ENABLE_INTRP)
1532         /* Allocate main thread stack on the Java heap. */
1533
1534         if (opt_intrp) {
1535                 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1536                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1537         }
1538 #endif
1539
1540         /* AFTER: threads_preinit */
1541
1542         if (!string_init())
1543                 vm_abort("vm_create: string_init failed");
1544
1545         /* AFTER: threads_preinit */
1546
1547         if (!utf8_init())
1548                 vm_abort("vm_create: utf8_init failed");
1549
1550         /* AFTER: thread_preinit */
1551
1552         if (!suck_init())
1553                 vm_abort("vm_create: suck_init failed");
1554
1555         suck_add_from_property("java.endorsed.dirs");
1556
1557         /* Now we have all options handled and we can print the version
1558            information.
1559
1560            AFTER: suck_add_from_property("java.endorsed.dirs"); */
1561
1562         if (opt_version)
1563                 version(opt_exit);
1564
1565         /* AFTER: utf8_init */
1566
1567         suck_add(_Jv_bootclasspath);
1568
1569         /* Now re-set some of the properties that may have changed. This
1570            must be done after _all_ environment variables have been
1571            processes (e.g. -jar handling).
1572
1573            AFTER: suck_add_from_property, since it may change the
1574            _Jv_bootclasspath pointer. */
1575
1576         if (!properties_postinit())
1577                 vm_abort("vm_create: properties_postinit failed");
1578
1579         /* initialize the classcache hashtable stuff: lock, hashtable
1580            (must be done _after_ threads_preinit) */
1581
1582         if (!classcache_init())
1583                 vm_abort("vm_create: classcache_init failed");
1584
1585         /* initialize the memory subsystem (must be done _after_
1586            threads_preinit) */
1587
1588         if (!memory_init())
1589                 vm_abort("vm_create: memory_init failed");
1590
1591         /* initialize the finalizer stuff (must be done _after_
1592            threads_preinit) */
1593
1594         if (!finalizer_init())
1595                 vm_abort("vm_create: finalizer_init failed");
1596
1597         /* initialize the codegen subsystems */
1598
1599         codegen_init();
1600
1601         /* initializes jit compiler */
1602
1603         jit_init();
1604
1605         /* machine dependent initialization */
1606
1607 #if defined(ENABLE_JIT)
1608 # if defined(ENABLE_INTRP)
1609         if (opt_intrp)
1610                 intrp_md_init();
1611         else
1612 # endif
1613                 md_init();
1614 #else
1615         intrp_md_init();
1616 #endif
1617
1618         /* initialize the loader subsystems (must be done _after_
1619        classcache_init) */
1620
1621         if (!loader_init())
1622                 vm_abort("vm_create: loader_init failed");
1623
1624         /* Link some important VM classes. */
1625         /* AFTER: utf8_init */
1626
1627         if (!linker_init())
1628                 vm_abort("vm_create: linker_init failed");
1629
1630         if (!primitive_init())
1631                 vm_abort("vm_create: primitive_init failed");
1632
1633         /* Initialize the native subsystem. */
1634
1635         if (!native_init())
1636                 vm_abort("vm_create: native_init failed");
1637
1638         if (!exceptions_init())
1639                 vm_abort("vm_create: exceptions_init failed");
1640
1641         if (!builtin_init())
1642                 vm_abort("vm_create: builtin_init failed");
1643
1644 #if defined(ENABLE_JNI)
1645         /* Initialize the JNI subsystem (must be done _before_
1646            threads_init, as threads_init can call JNI methods
1647            (e.g. NewGlobalRef). */
1648
1649         if (!jni_init())
1650                 vm_abort("vm_create: jni_init failed");
1651 #endif
1652
1653 #if defined(ENABLE_THREADS)
1654         if (!threads_init())
1655                 vm_abort("vm_create: threads_init failed");
1656 #endif
1657
1658 #if defined(ENABLE_PROFILING)
1659         /* initialize profiling */
1660
1661         if (!profile_init())
1662                 vm_abort("vm_create: profile_init failed");
1663 #endif
1664
1665 #if defined(ENABLE_THREADS)
1666         /* initialize recompilation */
1667
1668         if (!recompile_init())
1669                 vm_abort("vm_create: recompile_init failed");
1670
1671         /* start the signal handler thread */
1672
1673 #if defined(__LINUX__)
1674         /* XXX Remove for exact-GC. */
1675         if (threads_pthreads_implementation_nptl)
1676 #endif
1677                 if (!signal_start_thread())
1678                         vm_abort("vm_create: signal_start_thread failed");
1679
1680         /* finally, start the finalizer thread */
1681
1682         if (!finalizer_start_thread())
1683                 vm_abort("vm_create: finalizer_start_thread failed");
1684
1685 # if !defined(NDEBUG)
1686         /* start the memory profiling thread */
1687
1688         if (opt_verbosememory)
1689                 if (!memory_start_thread())
1690                         vm_abort("vm_create: memory_start_thread failed");
1691 # endif
1692
1693         /* start the recompilation thread (must be done before the
1694            profiling thread) */
1695
1696         if (!recompile_start_thread())
1697                 vm_abort("vm_create: recompile_start_thread failed");
1698
1699 # if defined(ENABLE_PROFILING)
1700         /* start the profile sampling thread */
1701
1702 /*      if (opt_prof) */
1703 /*              if (!profile_start_thread()) */
1704 /*                      vm_abort("vm_create: profile_start_thread failed"); */
1705 # endif
1706 #endif
1707
1708 #if defined(ENABLE_JVMTI)
1709         if (jvmti) {
1710                 /* add agent library to native library hashtable */
1711                 native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
1712         }
1713 #endif
1714
1715         /* increment the number of VMs */
1716
1717         vms++;
1718
1719         /* initialization is done */
1720
1721         vm_initializing = false;
1722
1723         /* everything's ok */
1724
1725         return true;
1726 }
1727
1728
1729 /* vm_run **********************************************************************
1730
1731    Runs the main-method of the passed class.
1732
1733 *******************************************************************************/
1734
1735 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
1736 {
1737         utf               *mainutf;
1738         classinfo         *mainclass;
1739         java_objectheader *e;
1740         methodinfo        *m;
1741         java_objectarray  *oa; 
1742         s4                 oalength;
1743         utf               *u;
1744         java_objectheader *s;
1745         s4                 status;
1746         s4                 i;
1747
1748 #if !defined(NDEBUG)
1749         if (compileall) {
1750                 vm_compile_all();
1751                 return;
1752         }
1753
1754         if (opt_method != NULL) {
1755                 vm_compile_method();
1756                 return;
1757         }
1758 #endif /* !defined(NDEBUG) */
1759
1760         /* should we run the main-method? */
1761
1762         if (mainstring == NULL)
1763                 usage();
1764
1765         /* set return value to OK */
1766
1767         status = 0;
1768
1769         if (opt_jar == true) {
1770                 /* open jar file with java.util.jar.JarFile */
1771
1772                 mainstring = vm_get_mainclass_from_jar(mainstring);
1773
1774                 if (mainstring == NULL)
1775                         vm_exit(1);
1776         }
1777
1778         /* load the main class */
1779
1780         mainutf = utf_new_char(mainstring);
1781
1782 #if defined(ENABLE_JAVAME_CLDC1_1)
1783         mainclass = load_class_bootstrap(mainutf);
1784 #else
1785         mainclass = load_class_from_sysloader(mainutf);
1786 #endif
1787
1788         /* error loading class */
1789
1790         e = exceptions_get_and_clear_exception();
1791
1792         if ((e != NULL) || (mainclass == NULL)) {
1793                 exceptions_throw_noclassdeffounderror_cause(e);
1794                 exceptions_print_stacktrace(); 
1795                 vm_exit(1);
1796         }
1797
1798         if (!link_class(mainclass)) {
1799                 exceptions_print_stacktrace();
1800                 vm_exit(1);
1801         }
1802                         
1803         /* find the `main' method of the main class */
1804
1805         m = class_resolveclassmethod(mainclass,
1806                                                                  utf_new_char("main"), 
1807                                                                  utf_new_char("([Ljava/lang/String;)V"),
1808                                                                  class_java_lang_Object,
1809                                                                  false);
1810
1811         if (exceptions_get_exception()) {
1812                 exceptions_print_stacktrace();
1813                 vm_exit(1);
1814         }
1815
1816         /* there is no main method or it isn't static */
1817
1818         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
1819                 exceptions_clear_exception();
1820                 exceptions_throw_nosuchmethoderror(mainclass,
1821                                                                                    utf_new_char("main"), 
1822                                                                                    utf_new_char("([Ljava/lang/String;)V"));
1823
1824                 exceptions_print_stacktrace();
1825                 vm_exit(1);
1826         }
1827
1828         /* build argument array */
1829
1830         oalength = vm_args->nOptions - opt_index;
1831
1832         oa = builtin_anewarray(oalength, class_java_lang_String);
1833
1834         for (i = 0; i < oalength; i++) {
1835                 u = utf_new_char(vm_args->options[opt_index + i].optionString);
1836                 s = javastring_new(u);
1837
1838                 oa->data[i] = s;
1839         }
1840
1841 #ifdef TYPEINFO_DEBUG_TEST
1842         /* test the typeinfo system */
1843         typeinfo_test();
1844 #endif
1845         /*class_showmethods(currentThread->group->header.vftbl->class); */
1846
1847 #if defined(ENABLE_JVMTI)
1848         jvmti_set_phase(JVMTI_PHASE_LIVE);
1849 #endif
1850
1851         /* set ThreadMXBean variables */
1852
1853         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1854         _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1855
1856         if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1857                 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1858                 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1859                         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1860
1861         /* start the main thread */
1862
1863         (void) vm_call_method(m, NULL, oa);
1864
1865         /* exception occurred? */
1866
1867         if (exceptions_get_exception()) {
1868                 exceptions_print_stacktrace();
1869                 status = 1;
1870         }
1871
1872         /* unload the JavaVM */
1873
1874         (void) vm_destroy(vm);
1875
1876         /* and exit */
1877
1878         vm_exit(status);
1879 }
1880
1881
1882 /* vm_destroy ******************************************************************
1883
1884    Unloads a Java VM and reclaims its resources.
1885
1886 *******************************************************************************/
1887
1888 s4 vm_destroy(JavaVM *vm)
1889 {
1890 #if defined(ENABLE_THREADS)
1891         threads_join_all_threads();
1892 #endif
1893
1894         /* everything's ok */
1895
1896         return 0;
1897 }
1898
1899
1900 /* vm_exit *********************************************************************
1901
1902    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1903
1904 *******************************************************************************/
1905
1906 void vm_exit(s4 status)
1907 {
1908         methodinfo *m;
1909
1910         /* signal that we are exiting */
1911
1912         vm_exiting = true;
1913
1914         assert(class_java_lang_System);
1915         assert(class_java_lang_System->state & CLASS_LOADED);
1916
1917 #if defined(ENABLE_JVMTI)
1918         if (jvmti || (dbgcom!=NULL)) {
1919                 jvmti_set_phase(JVMTI_PHASE_DEAD);
1920                 if (jvmti) jvmti_agentunload();
1921         }
1922 #endif
1923
1924         if (!link_class(class_java_lang_System)) {
1925                 exceptions_print_stacktrace();
1926                 exit(1);
1927         }
1928
1929         /* call java.lang.System.exit(I)V */
1930
1931         m = class_resolveclassmethod(class_java_lang_System,
1932                                                                  utf_new_char("exit"),
1933                                                                  utf_int__void,
1934                                                                  class_java_lang_Object,
1935                                                                  true);
1936         
1937         if (m == NULL) {
1938                 exceptions_print_stacktrace();
1939                 exit(1);
1940         }
1941
1942         /* call the exit function with passed exit status */
1943
1944         (void) vm_call_method(m, NULL, status);
1945
1946         /* If we had an exception, just ignore the exception and exit with
1947            the proper code. */
1948
1949         vm_shutdown(status);
1950 }
1951
1952
1953 /* vm_shutdown *****************************************************************
1954
1955    Terminates the system immediately without freeing memory explicitly
1956    (to be used only for abnormal termination).
1957         
1958 *******************************************************************************/
1959
1960 void vm_shutdown(s4 status)
1961 {
1962         if (opt_verbose 
1963 #if defined(ENABLE_STATISTICS)
1964                 || opt_getcompilingtime || opt_stat
1965 #endif
1966            ) 
1967         {
1968                 log_text("CACAO terminated by shutdown");
1969                 dolog("Exit status: %d\n", (s4) status);
1970
1971         }
1972
1973 #if defined(ENABLE_JVMTI)
1974         /* terminate cacaodbgserver */
1975         if (dbgcom!=NULL) {
1976                 pthread_mutex_lock(&dbgcomlock);
1977                 dbgcom->running=1;
1978                 pthread_mutex_unlock(&dbgcomlock);
1979                 jvmti_cacaodbgserver_quit();
1980         }       
1981 #endif
1982
1983         exit(status);
1984 }
1985
1986
1987 /* vm_exit_handler *************************************************************
1988
1989    The exit_handler function is called upon program termination.
1990
1991    ATTENTION: Don't free system resources here! Some threads may still
1992    be running as this is called from VMRuntime.exit(). The OS does the
1993    cleanup for us.
1994
1995 *******************************************************************************/
1996
1997 void vm_exit_handler(void)
1998 {
1999 #if !defined(NDEBUG)
2000         if (showmethods)
2001                 class_showmethods(mainclass);
2002
2003         if (showconstantpool)
2004                 class_showconstantpool(mainclass);
2005
2006         if (showutf)
2007                 utf_show();
2008
2009 # if defined(ENABLE_PROFILING)
2010         if (opt_prof)
2011                 profile_printstats();
2012 # endif
2013 #endif /* !defined(NDEBUG) */
2014
2015 #if defined(ENABLE_RT_TIMING)
2016         rt_timing_print_time_stats(stderr);
2017 #endif
2018
2019 #if defined(ENABLE_CYCLES_STATS)
2020         builtin_print_cycles_stats(stderr);
2021         stacktrace_print_cycles_stats(stderr);
2022 #endif
2023
2024         if (opt_verbose 
2025 #if defined(ENABLE_STATISTICS)
2026                 || opt_getcompilingtime || opt_stat
2027 #endif
2028            ) 
2029         {
2030                 log_text("CACAO terminated");
2031
2032 #if defined(ENABLE_STATISTICS)
2033                 if (opt_stat) {
2034                         print_stats();
2035 #ifdef TYPECHECK_STATISTICS
2036                         typecheck_print_statistics(get_logfile());
2037 #endif
2038                 }
2039
2040                 if (opt_getcompilingtime)
2041                         print_times();
2042 #endif /* defined(ENABLE_STATISTICS) */
2043         }
2044         /* vm_print_profile(stderr);*/
2045 }
2046
2047
2048 /* vm_abort ********************************************************************
2049
2050    Prints an error message and aborts the VM.
2051
2052 *******************************************************************************/
2053
2054 void vm_abort(const char *text, ...)
2055 {
2056         va_list ap;
2057
2058         /* print the log message */
2059
2060         log_start();
2061
2062         va_start(ap, text);
2063         log_vprint(text, ap);
2064         va_end(ap);
2065
2066         log_finish();
2067
2068         /* now abort the VM */
2069
2070         abort();
2071 }
2072
2073
2074 /* vm_get_mainclass_from_jar ***************************************************
2075
2076    Gets the name of the main class from a JAR's manifest file.
2077
2078 *******************************************************************************/
2079
2080 static char *vm_get_mainclass_from_jar(char *mainstring)
2081 {
2082         classinfo         *c;
2083         java_objectheader *o;
2084         methodinfo        *m;
2085         java_objectheader *s;
2086
2087         c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
2088
2089         if (c == NULL) {
2090                 exceptions_print_stacktrace();
2091                 return NULL;
2092         }
2093
2094         /* create JarFile object */
2095
2096         o = builtin_new(c);
2097
2098         if (o == NULL) {
2099                 exceptions_print_stacktrace();
2100                 return NULL;
2101         }
2102
2103         m = class_resolveclassmethod(c,
2104                                                                  utf_init, 
2105                                                                  utf_java_lang_String__void,
2106                                                                  class_java_lang_Object,
2107                                                                  true);
2108
2109         if (m == NULL) {
2110                 exceptions_print_stacktrace();
2111                 return NULL;
2112         }
2113
2114         s = javastring_new_from_ascii(mainstring);
2115
2116         (void) vm_call_method(m, o, s);
2117
2118         if (exceptions_get_exception()) {
2119                 exceptions_print_stacktrace();
2120                 return NULL;
2121         }
2122
2123         /* get manifest object */
2124
2125         m = class_resolveclassmethod(c,
2126                                                                  utf_new_char("getManifest"), 
2127                                                                  utf_new_char("()Ljava/util/jar/Manifest;"),
2128                                                                  class_java_lang_Object,
2129                                                                  true);
2130
2131         if (m == NULL) {
2132                 exceptions_print_stacktrace();
2133                 return NULL;
2134         }
2135
2136         o = vm_call_method(m, o);
2137
2138         if (o == NULL) {
2139                 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
2140                 return NULL;
2141         }
2142
2143
2144         /* get Main Attributes */
2145
2146         m = class_resolveclassmethod(o->vftbl->class,
2147                                                                  utf_new_char("getMainAttributes"), 
2148                                                                  utf_new_char("()Ljava/util/jar/Attributes;"),
2149                                                                  class_java_lang_Object,
2150                                                                  true);
2151
2152         if (m == NULL) {
2153                 exceptions_print_stacktrace();
2154                 return NULL;
2155         }
2156
2157         o = vm_call_method(m, o);
2158
2159         if (o == NULL) {
2160                 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
2161                 return NULL;
2162         }
2163
2164
2165         /* get property Main-Class */
2166
2167         m = class_resolveclassmethod(o->vftbl->class,
2168                                                                  utf_new_char("getValue"), 
2169                                                                  utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
2170                                                                  class_java_lang_Object,
2171                                                                  true);
2172
2173         if (m == NULL) {
2174                 exceptions_print_stacktrace();
2175                 return NULL;
2176         }
2177
2178         s = javastring_new_from_ascii("Main-Class");
2179
2180         o = vm_call_method(m, o, s);
2181
2182         if (o == NULL) {
2183                 exceptions_print_stacktrace();
2184                 return NULL;
2185         }
2186
2187         return javastring_tochar(o);
2188 }
2189
2190
2191 /* vm_compile_all **************************************************************
2192
2193    Compile all methods found in the bootclasspath.
2194
2195 *******************************************************************************/
2196
2197 #if !defined(NDEBUG)
2198 static void vm_compile_all(void)
2199 {
2200         classinfo              *c;
2201         methodinfo             *m;
2202         u4                      slot;
2203         classcache_name_entry  *nmen;
2204         classcache_class_entry *clsen;
2205         s4                      i;
2206
2207         /* create all classes found in the bootclasspath */
2208         /* XXX currently only works with zip/jar's */
2209
2210         loader_load_all_classes();
2211
2212         /* link all classes */
2213
2214         for (slot = 0; slot < hashtable_classcache.size; slot++) {
2215                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
2216
2217                 for (; nmen; nmen = nmen->hashlink) {
2218                         /* iterate over all class entries */
2219
2220                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
2221                                 c = clsen->classobj;
2222
2223                                 if (c == NULL)
2224                                         continue;
2225
2226                                 if (!(c->state & CLASS_LINKED)) {
2227                                         if (!link_class(c)) {
2228                                                 fprintf(stderr, "Error linking: ");
2229                                                 utf_fprint_printable_ascii_classname(stderr, c->name);
2230                                                 fprintf(stderr, "\n");
2231
2232                                                 /* print out exception and cause */
2233
2234                                                 exceptions_print_current_exception();
2235
2236                                                 /* goto next class */
2237
2238                                                 continue;
2239                                         }
2240                                 }
2241
2242                                 /* compile all class methods */
2243
2244                                 for (i = 0; i < c->methodscount; i++) {
2245                                         m = &(c->methods[i]);
2246
2247                                         if (m->jcode != NULL) {
2248                                                 if (!jit_compile(m)) {
2249                                                         fprintf(stderr, "Error compiling: ");
2250                                                         utf_fprint_printable_ascii_classname(stderr, c->name);
2251                                                         fprintf(stderr, ".");
2252                                                         utf_fprint_printable_ascii(stderr, m->name);
2253                                                         utf_fprint_printable_ascii(stderr, m->descriptor);
2254                                                         fprintf(stderr, "\n");
2255
2256                                                         /* print out exception and cause */
2257
2258                                                         exceptions_print_current_exception();
2259                                                 }
2260                                         }
2261                                 }
2262                         }
2263                 }
2264         }
2265 }
2266 #endif /* !defined(NDEBUG) */
2267
2268
2269 /* vm_compile_method ***********************************************************
2270
2271    Compile a specific method.
2272
2273 *******************************************************************************/
2274
2275 #if !defined(NDEBUG)
2276 static void vm_compile_method(void)
2277 {
2278         methodinfo *m;
2279
2280         /* create, load and link the main class */
2281
2282         mainclass = load_class_bootstrap(utf_new_char(mainstring));
2283
2284         if (mainclass == NULL)
2285                 exceptions_print_stacktrace();
2286
2287         if (!link_class(mainclass))
2288                 exceptions_print_stacktrace();
2289
2290         if (opt_signature != NULL) {
2291                 m = class_resolveclassmethod(mainclass,
2292                                                                          utf_new_char(opt_method),
2293                                                                          utf_new_char(opt_signature),
2294                                                                          mainclass,
2295                                                                          false);
2296         }
2297         else {
2298                 m = class_resolveclassmethod(mainclass,
2299                                                                          utf_new_char(opt_method),
2300                                                                          NULL,
2301                                                                          mainclass,
2302                                                                          false);
2303         }
2304
2305         if (m == NULL)
2306                 vm_abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
2307                                  opt_method, opt_signature ? opt_signature : "");
2308                 
2309         jit_compile(m);
2310 }
2311 #endif /* !defined(NDEBUG) */
2312
2313
2314 /* vm_vmargs_from_valist *******************************************************
2315
2316    XXX
2317
2318 *******************************************************************************/
2319
2320 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
2321                                                                   vm_arg *vmargs, va_list ap)
2322 {
2323         typedesc *paramtypes;
2324         s4        i;
2325
2326         paramtypes = m->parseddesc->paramtypes;
2327
2328         /* if method is non-static fill first block and skip `this' pointer */
2329
2330         i = 0;
2331
2332         if (o != NULL) {
2333                 /* the `this' pointer */
2334                 vmargs[0].type   = TYPE_ADR;
2335                 vmargs[0].data.l = (u8) (ptrint) o;
2336
2337                 paramtypes++;
2338                 i++;
2339         } 
2340
2341         for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
2342                 switch (paramtypes->type) {
2343                 case TYPE_INT:
2344                         vmargs[i].type   = TYPE_INT;
2345                         vmargs[i].data.l = (s8) va_arg(ap, s4);
2346                         break;
2347
2348                 case TYPE_LNG:
2349                         vmargs[i].type   = TYPE_LNG;
2350                         vmargs[i].data.l = (s8) va_arg(ap, s8);
2351                         break;
2352
2353                 case TYPE_FLT:
2354                         vmargs[i].type   = TYPE_FLT;
2355 #if defined(__ALPHA__)
2356                         /* this keeps the assembler function much simpler */
2357
2358                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2359 #else
2360                         vmargs[i].data.f = (jfloat) va_arg(ap, jdouble);
2361 #endif
2362                         break;
2363
2364                 case TYPE_DBL:
2365                         vmargs[i].type   = TYPE_DBL;
2366                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2367                         break;
2368
2369                 case TYPE_ADR: 
2370                         vmargs[i].type   = TYPE_ADR;
2371                         vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*);
2372                         break;
2373                 }
2374         }
2375 }
2376
2377
2378 /* vm_vmargs_from_jvalue *******************************************************
2379
2380    XXX
2381
2382 *******************************************************************************/
2383
2384 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
2385                                                                   vm_arg *vmargs, jvalue *args)
2386 {
2387         typedesc *paramtypes;
2388         s4        i;
2389         s4        j;
2390
2391         paramtypes = m->parseddesc->paramtypes;
2392
2393         /* if method is non-static fill first block and skip `this' pointer */
2394
2395         i = 0;
2396
2397         if (o != NULL) {
2398                 /* the `this' pointer */
2399                 vmargs[0].type   = TYPE_ADR;
2400                 vmargs[0].data.l = (u8) (ptrint) o;
2401
2402                 paramtypes++;
2403                 i++;
2404         } 
2405
2406         for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
2407                 switch (paramtypes->decltype) {
2408                 case TYPE_INT:
2409                         vmargs[i].type   = TYPE_INT;
2410                         vmargs[i].data.l = (s8) args[j].i;
2411                         break;
2412
2413                 case TYPE_LNG:
2414                         vmargs[i].type   = TYPE_LNG;
2415                         vmargs[i].data.l = (s8) args[j].j;
2416                         break;
2417
2418                 case TYPE_FLT:
2419                         vmargs[i].type = TYPE_FLT;
2420 #if defined(__ALPHA__)
2421                         /* this keeps the assembler function much simpler */
2422
2423                         vmargs[i].data.d = (jdouble) args[j].f;
2424 #else
2425                         vmargs[i].data.f = args[j].f;
2426 #endif
2427                         break;
2428
2429                 case TYPE_DBL:
2430                         vmargs[i].type   = TYPE_DBL;
2431                         vmargs[i].data.d = args[j].d;
2432                         break;
2433
2434                 case TYPE_ADR: 
2435                         vmargs[i].type   = TYPE_ADR;
2436                         vmargs[i].data.l = (u8) (ptrint) args[j].l;
2437                         break;
2438                 }
2439         }
2440 }
2441
2442
2443 /* vm_call_method **************************************************************
2444
2445    Calls a Java method with a variable number of arguments and returns
2446    an address.
2447
2448 *******************************************************************************/
2449
2450 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
2451 {
2452         va_list            ap;
2453         java_objectheader *ro;
2454
2455         va_start(ap, o);
2456         ro = vm_call_method_valist(m, o, ap);
2457         va_end(ap);
2458
2459         return ro;
2460 }
2461
2462
2463 /* vm_call_method_valist *******************************************************
2464
2465    Calls a Java method with a variable number of arguments, passed via
2466    a va_list, and returns an address.
2467
2468 *******************************************************************************/
2469
2470 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
2471                                                                                  va_list ap)
2472 {
2473         s4                 vmargscount;
2474         vm_arg            *vmargs;
2475         java_objectheader *ro;
2476         s4                 dumpsize;
2477
2478         /* mark start of dump memory area */
2479
2480         dumpsize = dump_size();
2481
2482         /* get number of Java method arguments */
2483
2484         vmargscount = m->parseddesc->paramcount;
2485
2486         /* allocate vm_arg array */
2487
2488         vmargs = DMNEW(vm_arg, vmargscount);
2489
2490         /* fill the vm_arg array from a va_list */
2491
2492         vm_vmargs_from_valist(m, o, vmargs, ap);
2493
2494         /* call the Java method */
2495
2496         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
2497
2498         /* release dump area */
2499
2500         dump_release(dumpsize);
2501
2502         return ro;
2503 }
2504
2505
2506 /* vm_call_method_jvalue *******************************************************
2507
2508    Calls a Java method with a variable number of arguments, passed via
2509    a jvalue array, and returns an address.
2510
2511 *******************************************************************************/
2512
2513 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
2514                                                                                  jvalue *args)
2515 {
2516         s4                 vmargscount;
2517         vm_arg            *vmargs;
2518         java_objectheader *ro;
2519         s4                 dumpsize;
2520
2521         /* mark start of dump memory area */
2522
2523         dumpsize = dump_size();
2524
2525         /* get number of Java method arguments */
2526
2527         vmargscount = m->parseddesc->paramcount;
2528
2529         /* allocate vm_arg array */
2530
2531         vmargs = DMNEW(vm_arg, vmargscount);
2532
2533         /* fill the vm_arg array from a va_list */
2534
2535         vm_vmargs_from_jvalue(m, o, vmargs, args);
2536
2537         /* call the Java method */
2538
2539         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
2540
2541         /* release dump area */
2542
2543         dump_release(dumpsize);
2544
2545         return ro;
2546 }
2547
2548
2549 /* vm_call_method_vmarg ********************************************************
2550
2551    Calls a Java method with a variable number of arguments, passed via
2552    a vm_arg array, and returns an address.
2553
2554 *******************************************************************************/
2555
2556 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
2557                                                                                 vm_arg *vmargs)
2558 {
2559         java_objectheader *o;
2560
2561         STATISTICS(count_calls_native_to_java++);
2562
2563 #if defined(ENABLE_JIT)
2564 # if defined(ENABLE_INTRP)
2565         if (opt_intrp)
2566                 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
2567         else
2568 # endif
2569                 o = asm_vm_call_method(m, vmargscount, vmargs);
2570 #else
2571         o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
2572 #endif
2573
2574         return o;
2575 }
2576
2577
2578 /* vm_call_method_int **********************************************************
2579
2580    Calls a Java method with a variable number of arguments and returns
2581    an integer (s4).
2582
2583 *******************************************************************************/
2584
2585 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
2586 {
2587         va_list ap;
2588         s4      i;
2589
2590         va_start(ap, o);
2591         i = vm_call_method_int_valist(m, o, ap);
2592         va_end(ap);
2593
2594         return i;
2595 }
2596
2597
2598 /* vm_call_method_int_valist ***************************************************
2599
2600    Calls a Java method with a variable number of arguments, passed via
2601    a va_list, and returns an integer (s4).
2602
2603 *******************************************************************************/
2604
2605 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
2606 {
2607         s4      vmargscount;
2608         vm_arg *vmargs;
2609         s4      i;
2610         s4      dumpsize;
2611
2612         /* mark start of dump memory area */
2613
2614         dumpsize = dump_size();
2615
2616         /* get number of Java method arguments */
2617
2618         vmargscount = m->parseddesc->paramcount;
2619
2620         /* allocate vm_arg array */
2621
2622         vmargs = DMNEW(vm_arg, vmargscount);
2623
2624         /* fill the vm_arg array from a va_list */
2625
2626         vm_vmargs_from_valist(m, o, vmargs, ap);
2627
2628         /* call the Java method */
2629
2630         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
2631
2632         /* release dump area */
2633
2634         dump_release(dumpsize);
2635
2636         return i;
2637 }
2638
2639
2640 /* vm_call_method_int_jvalue ***************************************************
2641
2642    Calls a Java method with a variable number of arguments, passed via
2643    a jvalue array, and returns an integer (s4).
2644
2645 *******************************************************************************/
2646
2647 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
2648 {
2649         s4      vmargscount;
2650         vm_arg *vmargs;
2651         s4      i;
2652         s4      dumpsize;
2653
2654         /* mark start of dump memory area */
2655
2656         dumpsize = dump_size();
2657
2658         /* get number of Java method arguments */
2659
2660         vmargscount = m->parseddesc->paramcount;
2661
2662         /* allocate vm_arg array */
2663
2664         vmargs = DMNEW(vm_arg, vmargscount);
2665
2666         /* fill the vm_arg array from a va_list */
2667
2668         vm_vmargs_from_jvalue(m, o, vmargs, args);
2669
2670         /* call the Java method */
2671
2672         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
2673
2674         /* release dump area */
2675
2676         dump_release(dumpsize);
2677
2678         return i;
2679 }
2680
2681
2682 /* vm_call_method_int_vmarg ****************************************************
2683
2684    Calls a Java method with a variable number of arguments, passed via
2685    a vm_arg array, and returns an integer (s4).
2686
2687 *******************************************************************************/
2688
2689 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2690 {
2691         s4 i;
2692
2693         STATISTICS(count_calls_native_to_java++);
2694
2695 #if defined(ENABLE_JIT)
2696 # if defined(ENABLE_INTRP)
2697         if (opt_intrp)
2698                 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
2699         else
2700 # endif
2701                 i = asm_vm_call_method_int(m, vmargscount, vmargs);
2702 #else
2703         i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
2704 #endif
2705
2706         return i;
2707 }
2708
2709
2710 /* vm_call_method_long *********************************************************
2711
2712    Calls a Java method with a variable number of arguments and returns
2713    a long (s8).
2714
2715 *******************************************************************************/
2716
2717 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
2718 {
2719         va_list ap;
2720         s8      l;
2721
2722         va_start(ap, o);
2723         l = vm_call_method_long_valist(m, o, ap);
2724         va_end(ap);
2725
2726         return l;
2727 }
2728
2729
2730 /* vm_call_method_long_valist **************************************************
2731
2732    Calls a Java method with a variable number of arguments, passed via
2733    a va_list, and returns a long (s8).
2734
2735 *******************************************************************************/
2736
2737 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
2738 {
2739         s4      vmargscount;
2740         vm_arg *vmargs;
2741         s8      l;
2742         s4      dumpsize;
2743
2744         /* mark start of dump memory area */
2745
2746         dumpsize = dump_size();
2747
2748         /* get number of Java method arguments */
2749
2750         vmargscount = m->parseddesc->paramcount;
2751
2752         /* allocate vm_arg array */
2753
2754         vmargs = DMNEW(vm_arg, vmargscount);
2755
2756         /* fill the vm_arg array from a va_list */
2757
2758         vm_vmargs_from_valist(m, o, vmargs, ap);
2759
2760         /* call the Java method */
2761
2762         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
2763
2764         /* release dump area */
2765
2766         dump_release(dumpsize);
2767
2768         return l;
2769 }
2770
2771
2772 /* vm_call_method_long_jvalue **************************************************
2773
2774    Calls a Java method with a variable number of arguments, passed via
2775    a jvalue array, and returns a long (s8).
2776
2777 *******************************************************************************/
2778
2779 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
2780 {
2781         s4      vmargscount;
2782         vm_arg *vmargs;
2783         s8      l;
2784         s4      dumpsize;
2785
2786         /* mark start of dump memory area */
2787
2788         dumpsize = dump_size();
2789
2790         /* get number of Java method arguments */
2791
2792         vmargscount = m->parseddesc->paramcount;
2793
2794         /* allocate vm_arg array */
2795
2796         vmargs = DMNEW(vm_arg, vmargscount);
2797
2798         /* fill the vm_arg array from a va_list */
2799
2800         vm_vmargs_from_jvalue(m, o, vmargs, args);
2801
2802         /* call the Java method */
2803
2804         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
2805
2806         /* release dump area */
2807
2808         dump_release(dumpsize);
2809
2810         return l;
2811 }
2812
2813
2814 /* vm_call_method_long_vmarg ***************************************************
2815
2816    Calls a Java method with a variable number of arguments, passed via
2817    a vm_arg array, and returns a long (s8).
2818
2819 *******************************************************************************/
2820
2821 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2822 {
2823         s8 l;
2824
2825         STATISTICS(count_calls_native_to_java++);
2826
2827 #if defined(ENABLE_JIT)
2828 # if defined(ENABLE_INTRP)
2829         if (opt_intrp)
2830                 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
2831         else
2832 # endif
2833                 l = asm_vm_call_method_long(m, vmargscount, vmargs);
2834 #else
2835         l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
2836 #endif
2837
2838         return l;
2839 }
2840
2841
2842 /* vm_call_method_float ********************************************************
2843
2844    Calls a Java method with a variable number of arguments and returns
2845    an float.
2846
2847 *******************************************************************************/
2848
2849 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
2850 {
2851         va_list ap;
2852         float   f;
2853
2854         va_start(ap, o);
2855         f = vm_call_method_float_valist(m, o, ap);
2856         va_end(ap);
2857
2858         return f;
2859 }
2860
2861
2862 /* vm_call_method_float_valist *************************************************
2863
2864    Calls a Java method with a variable number of arguments, passed via
2865    a va_list, and returns a float.
2866
2867 *******************************************************************************/
2868
2869 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
2870                                                                   va_list ap)
2871 {
2872         s4      vmargscount;
2873         vm_arg *vmargs;
2874         float   f;
2875         s4      dumpsize;
2876
2877         /* mark start of dump memory area */
2878
2879         dumpsize = dump_size();
2880
2881         /* get number of Java method arguments */
2882
2883         vmargscount = m->parseddesc->paramcount;
2884
2885         /* allocate vm_arg array */
2886
2887         vmargs = DMNEW(vm_arg, vmargscount);
2888
2889         /* fill the vm_arg array from a va_list */
2890
2891         vm_vmargs_from_valist(m, o, vmargs, ap);
2892
2893         /* call the Java method */
2894
2895         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2896
2897         /* release dump area */
2898
2899         dump_release(dumpsize);
2900
2901         return f;
2902 }
2903
2904
2905 /* vm_call_method_float_jvalue *************************************************
2906
2907    Calls a Java method with a variable number of arguments, passed via
2908    a jvalue array, and returns a float.
2909
2910 *******************************************************************************/
2911
2912 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
2913                                                                   jvalue *args)
2914 {
2915         s4      vmargscount;
2916         vm_arg *vmargs;
2917         float   f;
2918         s4      dumpsize;
2919
2920         /* mark start of dump memory area */
2921
2922         dumpsize = dump_size();
2923
2924         /* get number of Java method arguments */
2925
2926         vmargscount = m->parseddesc->paramcount;
2927
2928         /* allocate vm_arg array */
2929
2930         vmargs = DMNEW(vm_arg, vmargscount);
2931
2932         /* fill the vm_arg array from a va_list */
2933
2934         vm_vmargs_from_jvalue(m, o, vmargs, args);
2935
2936         /* call the Java method */
2937
2938         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2939
2940         /* release dump area */
2941
2942         dump_release(dumpsize);
2943
2944         return f;
2945 }
2946
2947
2948 /* vm_call_method_float_vmarg **************************************************
2949
2950    Calls a Java method with a variable number of arguments and returns
2951    an float.
2952
2953 *******************************************************************************/
2954
2955 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2956 {
2957         float f;
2958
2959         STATISTICS(count_calls_native_to_java++);
2960
2961 #if defined(ENABLE_JIT)
2962 # if defined(ENABLE_INTRP)
2963         if (opt_intrp)
2964                 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2965         else
2966 # endif
2967                 f = asm_vm_call_method_float(m, vmargscount, vmargs);
2968 #else
2969         f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2970 #endif
2971
2972         return f;
2973 }
2974
2975
2976 /* vm_call_method_double *******************************************************
2977
2978    Calls a Java method with a variable number of arguments and returns
2979    a double.
2980
2981 *******************************************************************************/
2982
2983 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
2984 {
2985         va_list ap;
2986         double  d;
2987
2988         va_start(ap, o);
2989         d = vm_call_method_double_valist(m, o, ap);
2990         va_end(ap);
2991
2992         return d;
2993 }
2994
2995
2996 /* vm_call_method_double_valist ************************************************
2997
2998    Calls a Java method with a variable number of arguments, passed via
2999    a va_list, and returns a double.
3000
3001 *******************************************************************************/
3002
3003 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
3004                                                                         va_list ap)
3005 {
3006         s4      vmargscount;
3007         vm_arg *vmargs;
3008         double  d;
3009         s4      dumpsize;
3010
3011         /* mark start of dump memory area */
3012
3013         dumpsize = dump_size();
3014
3015         /* get number of Java method arguments */
3016
3017         vmargscount = m->parseddesc->paramcount;
3018
3019         /* allocate vm_arg array */
3020
3021         vmargs = DMNEW(vm_arg, vmargscount);
3022
3023         /* fill the vm_arg array from a va_list */
3024
3025         vm_vmargs_from_valist(m, o, vmargs, ap);
3026
3027         /* call the Java method */
3028
3029         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
3030
3031         /* release dump area */
3032
3033         dump_release(dumpsize);
3034
3035         return d;
3036 }
3037
3038
3039 /* vm_call_method_double_jvalue ************************************************
3040
3041    Calls a Java method with a variable number of arguments, passed via
3042    a jvalue array, and returns a double.
3043
3044 *******************************************************************************/
3045
3046 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
3047                                                                         jvalue *args)
3048 {
3049         s4      vmargscount;
3050         vm_arg *vmargs;
3051         double  d;
3052         s4      dumpsize;
3053
3054         /* mark start of dump memory area */
3055
3056         dumpsize = dump_size();
3057
3058         /* get number of Java method arguments */
3059
3060         vmargscount = m->parseddesc->paramcount;
3061
3062         /* allocate vm_arg array */
3063
3064         vmargs = DMNEW(vm_arg, vmargscount);
3065
3066         /* fill the vm_arg array from a va_list */
3067
3068         vm_vmargs_from_jvalue(m, o, vmargs, args);
3069
3070         /* call the Java method */
3071
3072         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
3073
3074         /* release dump area */
3075
3076         dump_release(dumpsize);
3077
3078         return d;
3079 }
3080
3081
3082 /* vm_call_method_double_vmarg *************************************************
3083
3084    Calls a Java method with a variable number of arguments and returns
3085    a double.
3086
3087 *******************************************************************************/
3088
3089 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
3090                                                                    vm_arg *vmargs)
3091 {
3092         double d;
3093
3094         STATISTICS(count_calls_native_to_java++);
3095
3096 #if defined(ENABLE_JIT)
3097 # if defined(ENABLE_INTRP)
3098         if (opt_intrp)
3099                 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
3100         else
3101 # endif
3102                 d = asm_vm_call_method_double(m, vmargscount, vmargs);
3103 #else
3104         d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
3105 #endif
3106
3107         return d;
3108 }
3109
3110
3111 /*
3112  * These are local overrides for various environment variables in Emacs.
3113  * Please do not remove this and leave it at the end of the file, where
3114  * Emacs will automagically detect them.
3115  * ---------------------------------------------------------------------
3116  * Local variables:
3117  * mode: c
3118  * indent-tabs-mode: t
3119  * c-basic-offset: 4
3120  * tab-width: 4
3121  * End:
3122  */