Line data Source code
1 : /* src/vm/vm.cpp - VM startup and shutdown functions
2 :
3 : Copyright (C) 1996-2014
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 :
26 : #include "config.h"
27 :
28 : #include <cassert>
29 : #include <cerrno>
30 : #include <cstdlib>
31 : #include <exception>
32 : #include <stdint.h>
33 : #include <inttypes.h>
34 :
35 : #include "md-abi.hpp"
36 :
37 : #include "mm/codememory.hpp"
38 : #include "mm/dumpmemory.hpp"
39 : #include "mm/gc.hpp"
40 : #include "mm/memory.hpp"
41 :
42 : #include "native/jni.hpp"
43 : #include "native/llni.hpp"
44 : #include "native/localref.hpp"
45 : #include "native/native.hpp"
46 :
47 : #include "native/vm/nativevm.hpp"
48 :
49 : #include "threads/lock.hpp"
50 : #include "threads/thread.hpp"
51 :
52 : #include "toolbox/logging.hpp"
53 :
54 : #include "vm/array.hpp"
55 : #include "vm/assertion.hpp"
56 : #include "vm/classcache.hpp"
57 : #include "vm/exceptions.hpp"
58 : #include "vm/descriptor.hpp"
59 : #include "vm/finalizer.hpp"
60 : #include "vm/global.hpp"
61 : #include "vm/globals.hpp"
62 : #include "vm/hook.hpp"
63 : #include "vm/initialize.hpp"
64 : #include "vm/javaobjects.hpp"
65 : #include "vm/options.hpp"
66 : #include "vm/os.hpp"
67 : #include "vm/primitive.hpp"
68 : #include "vm/properties.hpp"
69 : #include "vm/rt-timing.hpp"
70 : #include "vm/signallocal.hpp"
71 : #include "vm/statistics.hpp"
72 : #include "vm/string.hpp"
73 : #include "vm/suck.hpp"
74 : #include "vm/types.hpp"
75 : #include "vm/vm.hpp"
76 :
77 : #include "vm/jit/abi-asm.hpp"
78 : #include "vm/jit/argument.hpp"
79 : #include "vm/jit/asmpart.hpp"
80 : #include "vm/jit/builtin.hpp"
81 : #include "vm/jit/code.hpp"
82 : #include "vm/jit/disass.hpp"
83 : #include "vm/jit/jit.hpp"
84 : #include "vm/jit/methodtree.hpp"
85 : #include "vm/jit/stacktrace.hpp"
86 : #include "vm/jit/trap.hpp"
87 :
88 : #include "vm/jit/optimizing/profile.hpp"
89 : #include "vm/jit/optimizing/recompiler.hpp"
90 :
91 : using namespace cacao;
92 :
93 :
94 : STAT_DECLARE_GROUP(function_call_stat)
95 : STAT_REGISTER_GROUP_VAR(u8,count_calls_native_to_java,0,"calls native to java","native-to-java calls",function_call_stat)
96 : /**
97 : * This is _the_ VM instance.
98 : */
99 : VM* VM::_vm = NULL;
100 :
101 :
102 : /* global variables ***********************************************************/
103 :
104 : s4 vms = 0; /* number of VMs created */
105 :
106 : #if !defined(NDEBUG)
107 : static classinfo *mainclass = NULL;
108 : #endif
109 :
110 : #if defined(ENABLE_INTRP)
111 : u1 *intrp_main_stack = NULL;
112 : #endif
113 :
114 :
115 : /* define heap sizes **********************************************************/
116 :
117 : #define HEAP_MAXSIZE 128 * 1024 * 1024 /* default 128MB */
118 : #define HEAP_STARTSIZE 2 * 1024 * 1024 /* default 2MB */
119 : #define STACK_SIZE 512 * 1024 /* default 512kB */
120 :
121 :
122 : /* define command line options ************************************************/
123 :
124 : enum {
125 : OPT_FOO,
126 :
127 : /* Java options */
128 :
129 : OPT_JAR,
130 :
131 : OPT_D32,
132 : OPT_D64,
133 :
134 : OPT_CLASSPATH,
135 : OPT_D,
136 :
137 : OPT_VERBOSE,
138 :
139 : OPT_VERSION,
140 : OPT_SHOWVERSION,
141 : OPT_FULLVERSION,
142 :
143 : OPT_HELP,
144 : OPT_X,
145 : OPT_XX,
146 :
147 : OPT_EA,
148 : OPT_DA,
149 : OPT_EA_NOARG,
150 : OPT_DA_NOARG,
151 :
152 :
153 : OPT_ESA,
154 : OPT_DSA,
155 :
156 : /* Java non-standard options */
157 :
158 : OPT_JIT,
159 : OPT_INTRP,
160 :
161 : OPT_BOOTCLASSPATH,
162 : OPT_BOOTCLASSPATH_A,
163 : OPT_BOOTCLASSPATH_P,
164 :
165 : OPT_BOOTCLASSPATH_C,
166 :
167 : #if defined(ENABLE_PROFILING)
168 : OPT_PROF,
169 : OPT_PROF_OPTION,
170 : #endif
171 :
172 : OPT_MS,
173 : OPT_MX,
174 :
175 : OPT_XCHECK_JNI,
176 :
177 : /* CACAO options */
178 :
179 : OPT_VERBOSE1,
180 :
181 : #if defined(ENABLE_STATISTICS)
182 : OPT_TIME,
183 : OPT_STAT,
184 : #endif
185 :
186 : OPT_LOG,
187 : OPT_CHECK,
188 : OPT_LOAD,
189 : OPT_SHOW,
190 : OPT_DEBUGCOLOR,
191 :
192 : #if defined(ENABLE_VERIFIER)
193 : OPT_NOVERIFY,
194 : OPT_XVERIFY_ALL,
195 : OPT_XVERIFY_NONE,
196 : #if defined(TYPECHECK_VERBOSE)
197 : OPT_VERBOSETC,
198 : #endif
199 : #endif /* defined(ENABLE_VERIFIER) */
200 :
201 : /* optimization options */
202 :
203 : #if defined(ENABLE_LOOP)
204 : OPT_OLOOP,
205 : #endif
206 :
207 : #if defined(ENABLE_IFCONV)
208 : OPT_IFCONV,
209 : #endif
210 :
211 : #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
212 : OPT_LSRA,
213 : #endif
214 :
215 : #if defined(ENABLE_INTRP)
216 : /* interpreter options */
217 :
218 : OPT_NO_DYNAMIC,
219 : OPT_NO_REPLICATION,
220 : OPT_NO_QUICKSUPER,
221 : OPT_STATIC_SUPERS,
222 : OPT_TRACE,
223 : #endif
224 :
225 : OPT_SS,
226 :
227 : #if defined(ENABLE_JVMTI)
228 : OPT_AGENTLIB,
229 : OPT_AGENTPATH,
230 : OPT_RUN,
231 : #endif
232 :
233 : #if defined(ENABLE_DEBUG_FILTER)
234 : OPT_FILTER_VERBOSECALL_INCLUDE,
235 : OPT_FILTER_VERBOSECALL_EXCLUDE,
236 : OPT_FILTER_SHOW_METHOD,
237 : #endif
238 :
239 : DUMMY
240 : };
241 :
242 :
243 : opt_struct opts[] = {
244 : { "foo", false, OPT_FOO },
245 :
246 : /* Java options */
247 :
248 : { "jar", false, OPT_JAR },
249 :
250 : { "d32", false, OPT_D32 },
251 : { "d64", false, OPT_D64 },
252 : { "client", false, OPT_IGNORE },
253 : { "server", false, OPT_IGNORE },
254 : { "jvm", false, OPT_IGNORE },
255 : { "hotspot", false, OPT_IGNORE },
256 :
257 : { "classpath", true, OPT_CLASSPATH },
258 : { "cp", true, OPT_CLASSPATH },
259 : { "D", true, OPT_D },
260 : { "version", false, OPT_VERSION },
261 : { "showversion", false, OPT_SHOWVERSION },
262 : { "fullversion", false, OPT_FULLVERSION },
263 : { "help", false, OPT_HELP },
264 : { "?", false, OPT_HELP },
265 : { "X", false, OPT_X },
266 : { "XX:", true, OPT_XX },
267 :
268 : { "ea:", true, OPT_EA },
269 : { "da:", true, OPT_DA },
270 : { "ea", false, OPT_EA_NOARG },
271 : { "da", false, OPT_DA_NOARG },
272 :
273 : { "enableassertions:", true, OPT_EA },
274 : { "disableassertions:", true, OPT_DA },
275 : { "enableassertions", false, OPT_EA_NOARG },
276 : { "disableassertions", false, OPT_DA_NOARG },
277 :
278 : { "esa", false, OPT_ESA },
279 : { "enablesystemassertions", false, OPT_ESA },
280 : { "dsa", false, OPT_DSA },
281 : { "disablesystemassertions", false, OPT_DSA },
282 :
283 : { "noasyncgc", false, OPT_IGNORE },
284 : #if defined(ENABLE_VERIFIER)
285 : { "noverify", false, OPT_NOVERIFY },
286 : { "Xverify:all", false, OPT_XVERIFY_ALL },
287 : { "Xverify:none", false, OPT_XVERIFY_NONE },
288 : #endif
289 : { "v", false, OPT_VERBOSE1 },
290 : { "verbose:", true, OPT_VERBOSE },
291 :
292 : #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
293 : { "verbosetc", false, OPT_VERBOSETC },
294 : #endif
295 : #if defined(ENABLE_STATISTICS)
296 : { "time", false, OPT_TIME },
297 : { "stat", false, OPT_STAT },
298 : #endif
299 : { "log", true, OPT_LOG },
300 : { "c", true, OPT_CHECK },
301 : { "l", false, OPT_LOAD },
302 :
303 : #if defined(ENABLE_LOOP)
304 : { "oloop", false, OPT_OLOOP },
305 : #endif
306 : #if defined(ENABLE_IFCONV)
307 : { "ifconv", false, OPT_IFCONV },
308 : #endif
309 : #if defined(ENABLE_LSRA)
310 : { "lsra", false, OPT_LSRA },
311 : #endif
312 : #if defined(ENABLE_SSA)
313 : { "lsra", true, OPT_LSRA },
314 : #endif
315 :
316 : #if defined(ENABLE_INTRP)
317 : /* interpreter options */
318 :
319 : { "trace", false, OPT_TRACE },
320 : { "static-supers", true, OPT_STATIC_SUPERS },
321 : { "no-dynamic", false, OPT_NO_DYNAMIC },
322 : { "no-replication", false, OPT_NO_REPLICATION },
323 : { "no-quicksuper", false, OPT_NO_QUICKSUPER },
324 : #endif
325 :
326 : /* JVMTI Agent Command Line Options */
327 : #if defined(ENABLE_JVMTI)
328 : { "agentlib:", true, OPT_AGENTLIB },
329 : { "agentpath:", true, OPT_AGENTPATH },
330 : #endif
331 :
332 : /* Java non-standard options */
333 :
334 : { "Xjit", false, OPT_JIT },
335 : { "Xint", false, OPT_INTRP },
336 : { "Xbootclasspath:", true, OPT_BOOTCLASSPATH },
337 : { "Xbootclasspath/a:", true, OPT_BOOTCLASSPATH_A },
338 : { "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P },
339 : { "Xbootclasspath/c:", true, OPT_BOOTCLASSPATH_C },
340 :
341 : #if defined(ENABLE_JVMTI)
342 : { "Xdebug", false, OPT_IGNORE },
343 : { "Xnoagent", false, OPT_IGNORE },
344 : { "Xrun", true, OPT_RUN },
345 : #endif
346 :
347 : { "Xms", true, OPT_MS },
348 : { "ms", true, OPT_MS },
349 : { "Xmx", true, OPT_MX },
350 : { "mx", true, OPT_MX },
351 : { "Xss", true, OPT_SS },
352 : { "ss", true, OPT_SS },
353 :
354 : { "Xcheck:jni", false, OPT_XCHECK_JNI },
355 :
356 : #if defined(ENABLE_PROFILING)
357 : { "Xprof:", true, OPT_PROF_OPTION },
358 : { "Xprof", false, OPT_PROF },
359 : #endif
360 :
361 : /* keep these at the end of the list */
362 :
363 : { "s", true, OPT_SHOW },
364 : { "debug-color", false, OPT_DEBUGCOLOR },
365 :
366 : #if defined(ENABLE_DEBUG_FILTER)
367 : { "XXfi", true, OPT_FILTER_VERBOSECALL_INCLUDE },
368 : { "XXfx", true, OPT_FILTER_VERBOSECALL_EXCLUDE },
369 : { "XXfm", true, OPT_FILTER_SHOW_METHOD },
370 : #endif
371 :
372 : { NULL, false, 0 }
373 : };
374 :
375 :
376 : /* usage ***********************************************************************
377 :
378 : Prints the correct usage syntax to stdout.
379 :
380 : *******************************************************************************/
381 :
382 24 : static void usage(void)
383 : {
384 24 : puts("Usage: cacao [-options] classname [arguments]");
385 24 : puts(" (to run a class file)");
386 24 : puts(" or cacao [-options] -jar jarfile [arguments]");
387 24 : puts(" (to run a standalone jar file)\n");
388 :
389 24 : puts("where options include:");
390 24 : puts(" -d32 use 32-bit data model if available");
391 24 : puts(" -d64 use 64-bit data model if available");
392 24 : puts(" -client compatibility (currently ignored)");
393 24 : puts(" -server compatibility (currently ignored)");
394 24 : puts(" -jvm compatibility (currently ignored)");
395 24 : puts(" -hotspot compatibility (currently ignored)\n");
396 :
397 24 : puts(" -cp <path> specify a path to look for classes");
398 24 : puts(" -classpath <path> specify a path to look for classes");
399 24 : puts(" -D<name>=<value> add an entry to the property list");
400 24 : puts(" -verbose[:class|gc|jni] enable specific verbose output");
401 24 : puts(" -version print product version and exit");
402 24 : puts(" -fullversion print jpackage-compatible product version and exit");
403 24 : puts(" -showversion print product version and continue");
404 24 : puts(" -help, -? print this help message");
405 24 : puts(" -X print help on non-standard Java options");
406 24 : puts(" -XX print help on debugging options");
407 24 : puts(" -ea[:<packagename>...|:<classname>]");
408 24 : puts(" -enableassertions[:<packagename>...|:<classname>]");
409 24 : puts(" enable assertions with specified granularity");
410 24 : puts(" -da[:<packagename>...|:<classname>]");
411 24 : puts(" -disableassertions[:<packagename>...|:<classname>]");
412 24 : puts(" disable assertions with specified granularity");
413 24 : puts(" -esa | -enablesystemassertions");
414 24 : puts(" enable system assertions");
415 24 : puts(" -dsa | -disablesystemassertions");
416 24 : puts(" disable system assertions");
417 :
418 : #if defined(ENABLE_JVMTI)
419 : puts(" -agentlib:<agent-lib-name>=<options>");
420 : puts(" load native agent library by library name");
421 : puts(" for additional help use: -agentlib:jdwp=help");
422 : puts(" -agentpath:<path-to-agent>=<options>");
423 : puts(" load native agent library by full pathname");
424 : #endif
425 :
426 : /* exit with error code */
427 :
428 24 : exit(1);
429 : }
430 :
431 :
432 0 : static void Xusage(void)
433 : {
434 : #if defined(ENABLE_JIT)
435 0 : puts(" -Xjit JIT mode execution (default)");
436 : #endif
437 : #if defined(ENABLE_INTRP)
438 : puts(" -Xint interpreter mode execution");
439 : #endif
440 0 : puts(" -Xbootclasspath:<zip/jar files and directories separated by :>");
441 0 : puts(" value is set as bootstrap class path");
442 0 : puts(" -Xbootclasspath/a:<zip/jar files and directories separated by :>");
443 0 : puts(" value is appended to the bootstrap class path");
444 0 : puts(" -Xbootclasspath/p:<zip/jar files and directories separated by :>");
445 0 : puts(" value is prepended to the bootstrap class path");
446 0 : puts(" -Xbootclasspath/c:<zip/jar files and directories separated by :>");
447 0 : puts(" value is used as Java core library, but the");
448 0 : puts(" hardcoded VM interface classes are prepended");
449 0 : printf(" -Xms<size> set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
450 0 : printf(" -Xmx<size> set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
451 0 : printf(" -Xss<size> set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
452 :
453 : #if defined(ENABLE_PROFILING)
454 : puts(" -Xprof[:bb] collect and print profiling data");
455 : #endif
456 :
457 : /* exit with error code */
458 :
459 0 : exit(1);
460 : }
461 :
462 :
463 : #if 0
464 : static void XXusage(void)
465 : {
466 : puts(" -v write state-information");
467 : #if !defined(NDEBUG)
468 : puts(" -verbose:jit enable specific verbose output");
469 : puts(" -debug-color colored output for ANSI terms");
470 : #endif
471 : #ifdef TYPECHECK_VERBOSE
472 : puts(" -verbosetc write debug messages while typechecking");
473 : #endif
474 : #if defined(ENABLE_VERIFIER)
475 : puts(" -noverify don't verify classfiles");
476 : #endif
477 : #if defined(ENABLE_STATISTICS)
478 : puts(" -time measure the runtime");
479 : puts(" -stat detailed compiler statistics");
480 : #endif
481 : puts(" -log logfile specify a name for the logfile");
482 : puts(" -c(heck)b(ounds) don't check array bounds");
483 : puts(" s(ync) don't check for synchronization");
484 : #if defined(ENABLE_LOOP)
485 : puts(" -oloop optimize array accesses in loops");
486 : #endif
487 : puts(" -l don't start the class after loading");
488 :
489 : puts(" -s... show...");
490 : puts(" (c)onstants the constant pool");
491 : puts(" (m)ethods class fields and methods");
492 : puts(" (u)tf the utf - hash");
493 : puts(" (i)ntermediate intermediate representation");
494 : #if defined(ENABLE_DISASSEMBLER)
495 : puts(" (a)ssembler disassembled listing");
496 : puts(" n(o)ps show NOPs in disassembler output");
497 : #endif
498 : puts(" (d)atasegment data segment listing");
499 :
500 : #if defined(ENABLE_IFCONV)
501 : puts(" -ifconv use if-conversion");
502 : #endif
503 : #if defined(ENABLE_LSRA)
504 : puts(" -lsra use linear scan register allocation");
505 : #endif
506 : #if defined(ENABLE_SSA)
507 : puts(" -lsra:... use linear scan register allocation (with SSA)");
508 : puts(" (d)ead code elimination");
509 : puts(" (c)opy propagation");
510 : #endif
511 : #if defined(ENABLE_DEBUG_FILTER)
512 : puts(" -XXfi <regex> begin of dynamic scope for verbosecall filter");
513 : puts(" -XXfx <regex> end of dynamic scope for verbosecall filter");
514 : puts(" -XXfm <regex> filter for show options");
515 : #endif
516 : /* exit with error code */
517 :
518 : exit(1);
519 : }
520 : #endif
521 :
522 :
523 : /* version *********************************************************************
524 :
525 : Only prints cacao version information.
526 :
527 : *******************************************************************************/
528 :
529 0 : static void version(bool opt_exit)
530 : {
531 0 : puts("java version \"" JAVA_VERSION "\"");
532 0 : puts("CACAO version " VERSION_FULL "\n");
533 :
534 0 : puts("Copyright (C) 1996-2014");
535 0 : puts("CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO");
536 0 : puts("This is free software; see the source for copying conditions. There is NO");
537 0 : puts("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
538 :
539 : /* exit normally, if requested */
540 :
541 0 : if (opt_exit)
542 0 : exit(0);
543 0 : }
544 :
545 :
546 : /* fullversion *****************************************************************
547 :
548 : Prints a Sun compatible version information (required e.g. by
549 : jpackage, www.jpackage.org).
550 :
551 : *******************************************************************************/
552 :
553 0 : static void fullversion(void)
554 : {
555 0 : puts("java full version \"cacao-" JAVA_VERSION "\"");
556 :
557 : /* exit normally */
558 :
559 0 : exit(0);
560 : }
561 :
562 :
563 : /* forward declarations *******************************************************/
564 :
565 : static char *vm_get_mainclass_from_jar(char *mainstring);
566 : #if !defined(NDEBUG)
567 : static void vm_compile_all(void);
568 : static void vm_compile_method(char* mainname);
569 : #endif
570 :
571 :
572 : /**
573 : * Implementation for JNI_CreateJavaVM. This function creates a VM
574 : * object.
575 : *
576 : * @param p_vm
577 : * @param p_env
578 : * @param vm_args
579 : *
580 : * @return true on success, false otherwise.
581 : */
582 165 : bool VM::create(JavaVM** p_vm, void** p_env, void* vm_args)
583 : {
584 : JavaVMInitArgs* _vm_args;
585 :
586 : // Get the arguments for the new JVM.
587 165 : _vm_args = (JavaVMInitArgs *) vm_args;
588 :
589 : // Instantiate a new VM.
590 : try {
591 165 : _vm = new VM(_vm_args);
592 : }
593 0 : catch (std::exception e) {
594 : // FIXME How can we delete the resources allocated?
595 : // /* release allocated memory */
596 : // FREE(env, _Jv_JNIEnv);
597 : // FREE(vm, _Jv_JavaVM);
598 :
599 0 : _vm = NULL;
600 :
601 0 : return false;
602 : }
603 :
604 : // Return the values.
605 :
606 163 : *p_vm = _vm->get_javavm();
607 163 : *p_env = _vm->get_jnienv();
608 :
609 163 : return true;
610 : }
611 :
612 :
613 : /**
614 : * C wrapper for VM::create.
615 : */
616 : extern "C" {
617 165 : bool VM_create(JavaVM** p_vm, void** p_env, void* vm_args)
618 : {
619 165 : return VM::create(p_vm, p_env, vm_args);
620 : }
621 : }
622 :
623 :
624 : /**
625 : * VM constructor.
626 : */
627 165 : VM::VM(JavaVMInitArgs* vm_args)
628 : {
629 : // Very first thing to do: we are initializing.
630 165 : _initializing = true;
631 :
632 : // Make sure logging works
633 :
634 :
635 : // Make ourself globally visible.
636 : // XXX Is this a good idea?
637 165 : _vm = this;
638 :
639 : /* create and fill a JavaVM structure */
640 :
641 165 : _javavm = new JavaVM();
642 :
643 : #if defined(ENABLE_JNI)
644 165 : _javavm->functions = &_Jv_JNIInvokeInterface;
645 : #endif
646 :
647 : /* get the VM and Env tables (must be set before vm_create) */
648 : /* XXX JVMTI Agents needs a JavaVM */
649 :
650 165 : _jnienv = new JNIEnv();
651 :
652 : #if defined(ENABLE_JNI)
653 165 : _jnienv->functions = &_Jv_JNINativeInterface;
654 : #endif
655 :
656 : /* actually create the JVM */
657 :
658 165 : int len = 0;
659 : char *p;
660 : char *boot_class_path;
661 165 : char *boot_class_path_p = NULL;
662 : char *class_path;
663 : int opt;
664 : bool opt_version;
665 : bool opt_exit;
666 :
667 : #if defined(ENABLE_JNI)
668 : /* Check the JNI version requested. */
669 :
670 165 : if (!jni_version_check(vm_args->version))
671 0 : throw std::exception();
672 : #endif
673 :
674 : /* We only support 1 JVM instance. */
675 :
676 165 : if (vms > 0)
677 0 : throw std::exception();
678 :
679 : /* Install the exit handler. */
680 :
681 165 : if (atexit(vm_exit_handler))
682 0 : os::abort("atexit failed: %s\n", strerror(errno));
683 :
684 : /* Set some options. */
685 :
686 165 : opt_version = false;
687 165 : opt_exit = false;
688 :
689 165 : opt_heapmaxsize = HEAP_MAXSIZE;
690 165 : opt_heapstartsize = HEAP_STARTSIZE;
691 165 : opt_stacksize = STACK_SIZE;
692 :
693 : // First of all, parse the -XX options.
694 165 : options_xx(vm_args);
695 :
696 : // After -XX options are parsed, print the build-time
697 : // configuration, if requested.
698 165 : if (opt_PrintConfig)
699 22 : print_build_time_config();
700 :
701 : /* We need to check if the actual size of a java.lang.Class object
702 : is smaller or equal than the assumption made in
703 : src/vm/class.hpp. */
704 :
705 : // FIXME We need to check the size of java.lang.Class!!!
706 : // if (sizeof(java_lang_Class) > sizeof(dummy_java_lang_Class))
707 : // vm_abort("vm_create: java_lang_Class structure is bigger than classinfo.object (%d > %d)", sizeof(java_lang_Class), sizeof(dummy_java_lang_Class));
708 :
709 : /* set the VM starttime */
710 :
711 165 : _starttime = builtin_currenttimemillis();
712 :
713 : /* iterate over all passed options */
714 :
715 568 : while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
716 240 : switch (opt) {
717 : case OPT_FOO:
718 0 : opt_foo = true;
719 0 : break;
720 :
721 : case OPT_IGNORE:
722 0 : break;
723 :
724 : case OPT_JAR:
725 0 : opt_jar = true;
726 0 : break;
727 :
728 : case OPT_D32:
729 : #if SIZEOF_VOID_P == 8
730 0 : puts("Running a 32-bit JVM is not supported on this platform.");
731 0 : exit(1);
732 : #endif
733 : break;
734 :
735 : case OPT_D64:
736 : #if SIZEOF_VOID_P == 4
737 : puts("Running a 64-bit JVM is not supported on this platform.");
738 : exit(1);
739 : #endif
740 0 : break;
741 :
742 : case OPT_CLASSPATH:
743 : /* Forget old classpath and set the argument as new
744 : classpath. */
745 :
746 : // FIXME Make class_path const char*.
747 5 : class_path = (char*) _properties.get("java.class.path");
748 :
749 5 : p = MNEW(char, strlen(opt_arg) + strlen("0"));
750 :
751 5 : strcpy(p, opt_arg);
752 :
753 : #if defined(ENABLE_JAVASE)
754 5 : _properties.put("java.class.path", p);
755 : #endif
756 :
757 5 : MFREE(class_path, char, strlen(class_path));
758 5 : break;
759 :
760 : case OPT_D:
761 19 : for (unsigned int i = 0; i < strlen(opt_arg); i++) {
762 19 : if (opt_arg[i] == '=') {
763 1 : opt_arg[i] = '\0';
764 1 : _properties.put(opt_arg, opt_arg + i + 1);
765 1 : goto opt_d_done;
766 : }
767 : }
768 :
769 : /* if no '=' is given, just create an empty property */
770 :
771 0 : _properties.put(opt_arg, "");
772 :
773 : opt_d_done:
774 1 : break;
775 :
776 : case OPT_BOOTCLASSPATH:
777 : /* Forget default bootclasspath and set the argument as
778 : new boot classpath. */
779 :
780 : /* Forget stored -Xbootclasspath/p value */
781 165 : if (boot_class_path_p != NULL) {
782 0 : MFREE(boot_class_path_p, char, len);
783 0 : boot_class_path_p = NULL;
784 : }
785 : // FIXME Make boot_class_path const char*.
786 165 : boot_class_path = (char*) _properties.get("sun.boot.class.path");
787 :
788 165 : p = MNEW(char, strlen(opt_arg) + strlen("0"));
789 :
790 165 : strcpy(p, opt_arg);
791 :
792 165 : _properties.put("sun.boot.class.path", p);
793 165 : _properties.put("java.boot.class.path", p);
794 :
795 165 : MFREE(boot_class_path, char, strlen(boot_class_path));
796 165 : break;
797 :
798 : case OPT_BOOTCLASSPATH_A:
799 : /* Append to bootclasspath. */
800 :
801 : // FIXME Make boot_class_path const char*.
802 1 : boot_class_path = (char*) _properties.get("sun.boot.class.path");
803 :
804 1 : len = strlen(boot_class_path);
805 :
806 : // XXX (char*) quick hack
807 : p = (char*) MREALLOC(boot_class_path,
808 : char,
809 : len + strlen("0"),
810 : len + strlen(":") +
811 1 : strlen(opt_arg) + strlen("0"));
812 :
813 1 : strcat(p, ":");
814 1 : strcat(p, opt_arg);
815 :
816 1 : _properties.put("sun.boot.class.path", p);
817 1 : _properties.put("java.boot.class.path", p);
818 1 : break;
819 :
820 : case OPT_BOOTCLASSPATH_P:
821 : /* Prepend to bootclasspath. */
822 : /* Note: we can not add this value directly to sun/java.boot.class.path
823 : because we need to take care of the ordering regarding the
824 : endorseddirs property */
825 :
826 0 : if (boot_class_path_p == NULL) {
827 0 : boot_class_path_p = MNEW(char, strlen(opt_arg) + strlen("0"));
828 0 : strcpy(boot_class_path_p, opt_arg);
829 : } else {
830 0 : len = strlen(boot_class_path_p);
831 0 : p = MNEW(char, strlen(opt_arg) + strlen(":") + len + strlen("0"));
832 0 : strcpy(p, opt_arg);
833 0 : strcat(p, ":");
834 0 : strcat(p, boot_class_path_p);
835 0 : MFREE(boot_class_path_p, char, len);
836 0 : boot_class_path_p = p;
837 : }
838 0 : break;
839 :
840 : case OPT_BOOTCLASSPATH_C:
841 : /* Use as Java core library, but prepend VM interface
842 : classes. */
843 :
844 : // FIXME Make boot_class_path const char*.
845 0 : boot_class_path = (char*) _properties.get("sun.boot.class.path");
846 :
847 : len =
848 : strlen(CACAO_VM_ZIP) +
849 : strlen(":") +
850 : strlen(opt_arg) +
851 0 : strlen("0");
852 :
853 0 : p = MNEW(char, len);
854 :
855 0 : strcpy(p, CACAO_VM_ZIP);
856 0 : strcat(p, ":");
857 0 : strcat(p, opt_arg);
858 :
859 0 : _properties.put("sun.boot.class.path", p);
860 0 : _properties.put("java.boot.class.path", p);
861 :
862 0 : MFREE(boot_class_path, char, strlen(boot_class_path));
863 0 : break;
864 :
865 : #if defined(ENABLE_JVMTI)
866 : case OPT_AGENTLIB:
867 : // Parse option argument.
868 : p = strchr(opt_arg, '=');
869 : if (p != NULL)
870 : *(p++) = '\0';
871 :
872 : _nativeagents.register_agent_library(opt_arg, p);
873 : break;
874 :
875 : case OPT_AGENTPATH:
876 : // Parse option argument.
877 : p = strchr(opt_arg, '=');
878 : if (p != NULL)
879 : *(p++) = '\0';
880 :
881 : _nativeagents.register_agent_path(opt_arg, p);
882 : break;
883 :
884 : case OPT_RUN:
885 : // Parse option argument.
886 : p = strchr(opt_arg, ':');
887 : if (p != NULL)
888 : *(p++) = '\0';
889 :
890 : _nativeagents.register_agent_library(opt_arg, p);
891 : break;
892 : #endif
893 :
894 : case OPT_MX:
895 : case OPT_MS:
896 : case OPT_SS:
897 : {
898 : char c;
899 : int j;
900 :
901 0 : c = opt_arg[strlen(opt_arg) - 1];
902 :
903 0 : if ((c == 'k') || (c == 'K')) {
904 0 : j = atoi(opt_arg) * 1024;
905 :
906 0 : } else if ((c == 'm') || (c == 'M')) {
907 0 : j = atoi(opt_arg) * 1024 * 1024;
908 :
909 : } else
910 0 : j = atoi(opt_arg);
911 :
912 0 : if (opt == OPT_MX)
913 0 : opt_heapmaxsize = j;
914 0 : else if (opt == OPT_MS)
915 0 : opt_heapstartsize = j;
916 : else
917 0 : opt_stacksize = j;
918 : }
919 0 : break;
920 :
921 : case OPT_XCHECK_JNI:
922 : // HotSpot compatibility option.
923 0 : break;
924 :
925 : case OPT_VERBOSE1:
926 0 : opt_verbose = true;
927 0 : break;
928 :
929 : case OPT_VERBOSE:
930 0 : if (strcmp("class", opt_arg) == 0) {
931 0 : opt_verboseclass = true;
932 : }
933 0 : else if (strcmp("gc", opt_arg) == 0) {
934 0 : opt_verbosegc = true;
935 : }
936 0 : else if (strcmp("jni", opt_arg) == 0) {
937 0 : opt_verbosejni = true;
938 : }
939 : #if !defined(NDEBUG)
940 0 : else if (strcmp("jit", opt_arg) == 0) {
941 0 : opt_verbose = true;
942 0 : loadverbose = true;
943 0 : initverbose = true;
944 0 : compileverbose = true;
945 : }
946 : #endif
947 : else {
948 0 : printf("Unknown -verbose option: %s\n", opt_arg);
949 0 : usage();
950 : }
951 0 : break;
952 :
953 : case OPT_DEBUGCOLOR:
954 0 : opt_debugcolor = true;
955 0 : break;
956 :
957 : #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
958 : case OPT_VERBOSETC:
959 : opt_typecheckverbose = true;
960 : break;
961 : #endif
962 :
963 : case OPT_VERSION:
964 0 : opt_version = true;
965 0 : opt_exit = true;
966 0 : break;
967 :
968 : case OPT_FULLVERSION:
969 0 : fullversion();
970 0 : break;
971 :
972 : case OPT_SHOWVERSION:
973 0 : opt_version = true;
974 0 : break;
975 :
976 : #if defined(ENABLE_VERIFIER)
977 : case OPT_XVERIFY_ALL:
978 0 : opt_verify = true;
979 0 : break;
980 :
981 : case OPT_NOVERIFY:
982 : case OPT_XVERIFY_NONE:
983 0 : opt_verify = false;
984 0 : break;
985 : #endif
986 :
987 : #if defined(ENABLE_STATISTICS)
988 : case OPT_TIME:
989 : opt_getcompilingtime = true;
990 : opt_getloadingtime = true;
991 : break;
992 :
993 : case OPT_STAT:
994 : opt_stat = true;
995 : break;
996 : #endif
997 :
998 : case OPT_LOG:
999 0 : log_init(opt_arg);
1000 0 : break;
1001 :
1002 : case OPT_CHECK:
1003 0 : for (unsigned int i = 0; i < strlen(opt_arg); i++) {
1004 0 : switch (opt_arg[i]) {
1005 : case 'b':
1006 0 : checkbounds = false;
1007 0 : break;
1008 : case 's':
1009 0 : checksync = false;
1010 0 : break;
1011 : default:
1012 0 : usage();
1013 : }
1014 : }
1015 0 : break;
1016 :
1017 : case OPT_LOAD:
1018 0 : opt_run = false;
1019 0 : makeinitializations = false;
1020 0 : break;
1021 :
1022 : case OPT_SHOW: /* Display options */
1023 4 : for (unsigned int i = 0; i < strlen(opt_arg); i++) {
1024 4 : switch (opt_arg[i]) {
1025 : case 'c':
1026 0 : showconstantpool = true;
1027 0 : break;
1028 :
1029 : case 'u':
1030 0 : showutf = true;
1031 0 : break;
1032 :
1033 : case 'm':
1034 0 : showmethods = true;
1035 0 : break;
1036 :
1037 : case 'i':
1038 2 : opt_showintermediate = true;
1039 2 : compileverbose = true;
1040 2 : break;
1041 :
1042 : #if defined(ENABLE_DISASSEMBLER)
1043 : case 'a':
1044 : opt_showdisassemble = true;
1045 : compileverbose = true;
1046 : break;
1047 : #endif
1048 :
1049 : case 'd':
1050 0 : opt_showddatasegment = true;
1051 0 : break;
1052 :
1053 : default:
1054 2 : usage();
1055 : }
1056 : }
1057 0 : break;
1058 :
1059 : #if defined(ENABLE_LOOP)
1060 : case OPT_OLOOP:
1061 : opt_loops = true;
1062 : break;
1063 : #endif
1064 :
1065 : #if defined(ENABLE_IFCONV)
1066 : case OPT_IFCONV:
1067 0 : opt_ifconv = true;
1068 0 : break;
1069 : #endif
1070 :
1071 : #if defined(ENABLE_LSRA)
1072 : case OPT_LSRA:
1073 : opt_lsra = true;
1074 : break;
1075 : #endif
1076 : #if defined(ENABLE_SSA)
1077 : case OPT_LSRA:
1078 : opt_lsra = true;
1079 : for (unsigned int i = 0; i < strlen(opt_arg); i++) {
1080 : switch (opt_arg[i]) {
1081 : case 'c':
1082 : opt_ssa_cp = true;
1083 : break;
1084 :
1085 : case 'd':
1086 : opt_ssa_dce = true;
1087 : break;
1088 :
1089 : case ':':
1090 : break;
1091 :
1092 : default:
1093 : usage();
1094 : }
1095 : }
1096 : break;
1097 : #endif
1098 :
1099 : case OPT_HELP:
1100 0 : usage();
1101 0 : break;
1102 :
1103 : case OPT_X:
1104 0 : Xusage();
1105 0 : break;
1106 :
1107 : case OPT_XX:
1108 : /* Already parsed. */
1109 22 : break;
1110 :
1111 : case OPT_EA:
1112 : #if defined(ENABLE_ASSERTION)
1113 10 : assertion_ea_da(opt_arg, true);
1114 : #endif
1115 10 : break;
1116 :
1117 : case OPT_DA:
1118 : #if defined(ENABLE_ASSERTION)
1119 10 : assertion_ea_da(opt_arg, false);
1120 : #endif
1121 10 : break;
1122 :
1123 : case OPT_EA_NOARG:
1124 : #if defined(ENABLE_ASSERTION)
1125 12 : assertion_user_enabled = true;
1126 : #endif
1127 12 : break;
1128 :
1129 : case OPT_DA_NOARG:
1130 : #if defined(ENABLE_ASSERTION)
1131 10 : assertion_user_enabled = false;
1132 : #endif
1133 10 : break;
1134 :
1135 : case OPT_ESA:
1136 : #if defined(ENABLE_ASSERTION)
1137 2 : assertion_system_enabled = true;
1138 : #endif
1139 2 : break;
1140 :
1141 : case OPT_DSA:
1142 : #if defined(ENABLE_ASSERTION)
1143 0 : assertion_system_enabled = false;
1144 : #endif
1145 0 : break;
1146 :
1147 : #if defined(ENABLE_PROFILING)
1148 : case OPT_PROF_OPTION:
1149 : /* use <= to get the last \0 too */
1150 :
1151 : for (unsigned int i = 0, j = 0; i <= strlen(opt_arg); i++) {
1152 : if (opt_arg[i] == ',')
1153 : opt_arg[i] = '\0';
1154 :
1155 : if (opt_arg[i] == '\0') {
1156 : if (strcmp("bb", opt_arg + j) == 0)
1157 : opt_prof_bb = true;
1158 :
1159 : else {
1160 : fprintf(stderr, "Unknown option: -Xprof:%s\n", opt_arg + j);
1161 : usage();
1162 : }
1163 :
1164 : /* set k to next char */
1165 :
1166 : j = i + 1;
1167 : }
1168 : }
1169 : /* fall through */
1170 :
1171 : case OPT_PROF:
1172 : opt_prof = true;
1173 : break;
1174 : #endif
1175 :
1176 : case OPT_JIT:
1177 : #if defined(ENABLE_JIT)
1178 0 : opt_jit = true;
1179 : #else
1180 : printf("-Xjit option not enabled.\n");
1181 : exit(1);
1182 : #endif
1183 0 : break;
1184 :
1185 : case OPT_INTRP:
1186 : #if defined(ENABLE_INTRP)
1187 : opt_intrp = true;
1188 : #else
1189 0 : printf("-Xint option not enabled.\n");
1190 0 : exit(1);
1191 : #endif
1192 : break;
1193 :
1194 : #if defined(ENABLE_INTRP)
1195 : case OPT_STATIC_SUPERS:
1196 : opt_static_supers = atoi(opt_arg);
1197 : break;
1198 :
1199 : case OPT_NO_DYNAMIC:
1200 : opt_no_dynamic = true;
1201 : break;
1202 :
1203 : case OPT_NO_REPLICATION:
1204 : opt_no_replication = true;
1205 : break;
1206 :
1207 : case OPT_NO_QUICKSUPER:
1208 : opt_no_quicksuper = true;
1209 : break;
1210 :
1211 : case OPT_TRACE:
1212 : vm_debug = true;
1213 : break;
1214 : #endif
1215 :
1216 : #if defined(ENABLE_DEBUG_FILTER)
1217 : case OPT_FILTER_VERBOSECALL_INCLUDE:
1218 0 : opt_filter_verbosecall_include = opt_arg;
1219 0 : break;
1220 :
1221 : case OPT_FILTER_VERBOSECALL_EXCLUDE:
1222 0 : opt_filter_verbosecall_exclude = opt_arg;
1223 0 : break;
1224 :
1225 : case OPT_FILTER_SHOW_METHOD:
1226 0 : opt_filter_show_method = opt_arg;
1227 0 : break;
1228 :
1229 : #endif
1230 : default:
1231 : fprintf(stderr, "Unknown option: %s\n",
1232 0 : vm_args->options[opt_index++].optionString);
1233 : }
1234 : }
1235 :
1236 : // Print the preliminary run-time VM configuration after options
1237 : // are parsed.
1238 163 : if (opt_PrintConfig)
1239 22 : print_run_time_config();
1240 :
1241 : /* initialize the garbage collector */
1242 :
1243 163 : gc_init(opt_heapmaxsize, opt_heapstartsize);
1244 :
1245 : /* AFTER: gc_init */
1246 :
1247 163 : threads_preinit();
1248 163 : lock_init();
1249 :
1250 : /* install architecture dependent signal handlers */
1251 :
1252 163 : if (!signal_init())
1253 0 : os::abort("vm_create: signal_init failed");
1254 :
1255 : #if defined(ENABLE_INTRP)
1256 : /* Allocate main thread stack on the Java heap. */
1257 :
1258 : if (opt_intrp) {
1259 : intrp_main_stack = GCMNEW(u1, opt_stacksize);
1260 : MSET(intrp_main_stack, 0, u1, opt_stacksize);
1261 : }
1262 : #endif
1263 :
1264 : /* AFTER: threads_preinit */
1265 :
1266 163 : JavaString::initialize();
1267 :
1268 : /* AFTER: threads_preinit */
1269 :
1270 163 : Utf8String::initialize();
1271 :
1272 : // Hook point before the VM is initialized.
1273 163 : Hook::vm_preinit();
1274 :
1275 : #if defined(ENABLE_JVMTI)
1276 : // AFTER: utf8_init
1277 : if (!_nativeagents.load_agents())
1278 : os::abort("vm_create: load_agents failed");
1279 : #endif
1280 :
1281 : /* AFTER: thread_preinit */
1282 :
1283 : /* Add -Xbootclasspath/p if it exists */
1284 163 : if (boot_class_path_p != NULL)
1285 0 : _suckclasspath.add(boot_class_path_p);
1286 :
1287 163 : _suckclasspath.add_from_property("java.endorsed.dirs");
1288 :
1289 : /* Now we have all options handled and we can print the version
1290 : information.
1291 :
1292 : AFTER: suck_add_from_property("java.endorsed.dirs"); */
1293 :
1294 163 : if (opt_version)
1295 0 : version(opt_exit);
1296 :
1297 : /* AFTER: utf8_init */
1298 :
1299 : // FIXME Make boot_class_path const char*.
1300 163 : boot_class_path = (char*) _properties.get("sun.boot.class.path");
1301 163 : _suckclasspath.add(boot_class_path);
1302 :
1303 : /* initialize the classcache hashtable stuff: lock, hashtable
1304 : (must be done _after_ threads_preinit) */
1305 :
1306 163 : if (!classcache_init())
1307 0 : os::abort("vm_create: classcache_init failed");
1308 :
1309 : /* Initialize the code memory management. */
1310 : /* AFTER: threads_preinit */
1311 :
1312 163 : codememory_init();
1313 :
1314 : /* initialize the finalizer stuff (must be done _after_
1315 : threads_preinit) */
1316 :
1317 163 : if (!finalizer_init())
1318 0 : os::abort("vm_create: finalizer_init failed");
1319 :
1320 : /* Initialize the JIT compiler. */
1321 :
1322 163 : jit_init();
1323 163 : code_init();
1324 163 : methodtree_init();
1325 :
1326 : /* AFTER: utf8_init, classcache_init */
1327 :
1328 163 : loader_preinit();
1329 163 : linker_preinit();
1330 :
1331 : // AFTER: loader_preinit, linker_preinit
1332 163 : Primitive::initialize_table();
1333 :
1334 163 : loader_init();
1335 163 : jobjects_register_dyn_offsets();
1336 163 : linker_init();
1337 :
1338 : // AFTER: loader_init, linker_init
1339 163 : Primitive::post_initialize_table();
1340 163 : method_init();
1341 :
1342 : #if defined(ENABLE_JIT)
1343 163 : trap_init();
1344 : #endif
1345 :
1346 163 : if (!builtin_init())
1347 0 : os::abort("vm_create: builtin_init failed");
1348 :
1349 : /* Register the native methods implemented in the VM. */
1350 : /* BEFORE: threads_init */
1351 :
1352 163 : nativevm_preinit();
1353 :
1354 : #if defined(ENABLE_JNI)
1355 : /* Initialize the JNI subsystem (must be done _before_
1356 : threads_init, as threads_init can call JNI methods
1357 : (e.g. NewGlobalRef). */
1358 :
1359 163 : if (!jni_init())
1360 0 : os::abort("vm_create: jni_init failed");
1361 : #endif
1362 :
1363 : #if defined(ENABLE_JNI) || defined(ENABLE_HANDLES)
1364 : /* Initialize the local reference table for the main thread. */
1365 : /* BEFORE: threads_init */
1366 :
1367 163 : if (!localref_table_init())
1368 0 : os::abort("vm_create: localref_table_init failed");
1369 : #endif
1370 :
1371 : /* Iinitialize some important system classes. */
1372 : /* BEFORE: threads_init */
1373 :
1374 163 : initialize_init();
1375 163 : threads_init();
1376 :
1377 : /* Initialize the native VM subsystem. */
1378 : /* AFTER: threads_init (at least for SUN's classes) */
1379 :
1380 163 : if (!nativevm_init())
1381 0 : os::abort("vm_create: nativevm_init failed");
1382 :
1383 : #if defined(ENABLE_PROFILING)
1384 : /* initialize profiling */
1385 :
1386 : if (!profile_init())
1387 : os::abort("vm_create: profile_init failed");
1388 : #endif
1389 :
1390 : /* start the signal handler thread */
1391 :
1392 : #if defined(__LINUX__)
1393 : /* XXX Remove for exact-GC. */
1394 163 : if (threads_pthreads_implementation_nptl)
1395 : #endif
1396 163 : if (!signal_start_thread())
1397 0 : os::abort("vm_create: signal_start_thread failed");
1398 :
1399 : /* finally, start the finalizer thread */
1400 :
1401 163 : if (!finalizer_start_thread())
1402 0 : os::abort("vm_create: finalizer_start_thread failed");
1403 :
1404 : #if !defined(NDEBUG)
1405 : /* start the memory profiling thread */
1406 :
1407 163 : if (opt_ProfileMemoryUsage || opt_ProfileGCMemoryUsage)
1408 0 : if (!memory_start_thread())
1409 0 : os::abort("vm_create: memory_start_thread failed");
1410 : #endif
1411 :
1412 : #ifdef ENABLE_THREADS
1413 : // Start the recompilation thread (must be done before the
1414 : // profiling thread).
1415 : // FIXME Only works for one recompiler.
1416 163 : _recompiler.start();
1417 : #endif
1418 :
1419 : #if defined(ENABLE_PROFILING)
1420 : /* start the profile sampling thread */
1421 :
1422 : /* if (opt_prof) */
1423 : /* if (!profile_start_thread()) */
1424 : /* os::abort("vm_create: profile_start_thread failed"); */
1425 : #endif
1426 :
1427 : /* Increment the number of VMs. */
1428 :
1429 163 : vms++;
1430 :
1431 : // Initialization is done, VM is created.
1432 163 : _created = true;
1433 163 : _initializing = false;
1434 :
1435 : // Set the VM inittime.
1436 163 : _inittime = builtin_currenttimemillis();
1437 :
1438 : // Hook point after the VM is initialized.
1439 163 : Hook::vm_init();
1440 :
1441 : // Print the run-time VM configuration after all stuff is set and
1442 : // the VM is initialized.
1443 163 : if (opt_PrintConfig)
1444 22 : print_run_time_config();
1445 :
1446 : // Start runtime agents after the VM is created.
1447 163 : if (!start_runtime_agents())
1448 0 : os::abort("vm_create: start_runtime_agents failed");
1449 0 : }
1450 :
1451 :
1452 : /**
1453 : * Print build-time (default) VM configuration.
1454 : */
1455 22 : void VM::print_build_time_config(void)
1456 : {
1457 22 : puts("CACAO " VERSION_FULL " configure/build options:");
1458 22 : puts("");
1459 22 : puts(" ./configure: " VERSION_CONFIGURE_ARGS "");
1460 : #if defined(__VERSION__)
1461 22 : puts(" CC : " VERSION_CC " (" __VERSION__ ")");
1462 22 : puts(" CXX : " VERSION_CXX " (" __VERSION__ ")");
1463 : #else
1464 : puts(" CC : " VERSION_CC "");
1465 : puts(" CXX : " VERSION_CXX "");
1466 : #endif
1467 22 : puts(" CFLAGS : " VERSION_CFLAGS "");
1468 22 : puts(" CXXFLAGS : " VERSION_CXXFLAGS "");
1469 22 : puts(" CPPFLAGS : " VERSION_CPPFLAGS "");
1470 :
1471 22 : puts("");
1472 :
1473 22 : puts("Build-time (default) variables:\n");
1474 22 : printf(" maximum heap size : %d\n", HEAP_MAXSIZE);
1475 22 : printf(" initial heap size : %d\n", HEAP_STARTSIZE);
1476 22 : printf(" stack size : %d\n", STACK_SIZE);
1477 :
1478 : #if defined(ENABLE_JRE_LAYOUT)
1479 : // When we're building with JRE-layout, the default paths are the
1480 : // same as the runtime paths.
1481 : #else
1482 : # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1483 22 : puts(" gnu.classpath.boot.library.path: " JAVA_RUNTIME_LIBRARY_LIBDIR);
1484 22 : puts(" java.boot.class.path : " CACAO_VM_ZIP ":" JAVA_RUNTIME_LIBRARY_CLASSES);
1485 : # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1486 : puts(" sun.boot.library.path : " JAVA_RUNTIME_LIBRARY_LIBDIR);
1487 : puts(" java.boot.class.path : " JAVA_RUNTIME_LIBRARY_CLASSES);
1488 : # endif
1489 : #endif
1490 :
1491 22 : puts("");
1492 22 : }
1493 :
1494 :
1495 : /**
1496 : * Print run-time VM configuration.
1497 : */
1498 44 : void VM::print_run_time_config()
1499 : {
1500 44 : puts("Run-time variables:\n");
1501 44 : printf(" maximum heap size : %d\n", opt_heapmaxsize);
1502 44 : printf(" initial heap size : %d\n", opt_heapstartsize);
1503 44 : printf(" stack size : %d\n", opt_stacksize);
1504 :
1505 : #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1506 44 : printf(" gnu.classpath.boot.library.path: %s\n", _properties.get("gnu.classpath.boot.library.path"));
1507 : #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1508 : printf(" sun.boot.library.path : %s\n", _properties.get("sun.boot.library.path"));
1509 : #endif
1510 :
1511 44 : printf(" java.boot.class.path : %s\n", _properties.get("java.boot.class.path"));
1512 44 : printf(" java.class.path : %s\n", _properties.get("java.class.path"));
1513 :
1514 44 : puts("");
1515 44 : }
1516 :
1517 :
1518 : /**
1519 : * Start runtime agents which are provided by the JRE but need to be
1520 : * started explicitly by the VM.
1521 : */
1522 163 : bool VM::start_runtime_agents()
1523 : {
1524 : #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1525 :
1526 : // Nothing to do.
1527 :
1528 : #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1529 :
1530 : // Check whether the management agent should be loaded.
1531 : if ((_properties.get("com.sun.management.jmxremote") != NULL) ||
1532 : (_properties.get("com.sun.management.snmp") != NULL))
1533 : {
1534 :
1535 : // Load the management agent class.
1536 : classinfo* class_sun_management_Agent;
1537 : if (!(class_sun_management_Agent = load_class_from_sysloader(Utf8String::from_utf8("sun/management/Agent"))))
1538 : return false;
1539 :
1540 : // Link the management agent class.
1541 : if (!link_class(class_sun_management_Agent))
1542 : return false;
1543 :
1544 : // Actually start the management agent.
1545 : methodinfo* m = class_resolveclassmethod(class_sun_management_Agent,
1546 : Utf8String::from_utf8("startAgent"),
1547 : utf8::void__void,
1548 : class_java_lang_Object,
1549 : false);
1550 :
1551 : if (m == NULL)
1552 : return false;
1553 :
1554 : (void) vm_call_method(m, NULL);
1555 :
1556 : if (exceptions_get_exception() != NULL)
1557 : return false;
1558 : }
1559 :
1560 : #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1561 :
1562 : // Nothing to do.
1563 :
1564 : #else
1565 : # error unknown classpath configuration
1566 : #endif
1567 :
1568 163 : return true;
1569 : }
1570 :
1571 : static void write_logfiles();
1572 :
1573 : /* vm_run **********************************************************************
1574 :
1575 : Runs the main-method of the passed class.
1576 :
1577 : *******************************************************************************/
1578 :
1579 163 : void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
1580 : {
1581 : methodinfo* m;
1582 : int status;
1583 :
1584 : #if !defined(NDEBUG)
1585 163 : if (opt_CompileAll) {
1586 0 : vm_compile_all();
1587 : /* write logfiles */
1588 0 : write_logfiles();
1589 0 : return;
1590 : }
1591 : #endif
1592 :
1593 : /* Get the main class or jar file argument. */
1594 :
1595 163 : char* mainname = NULL;
1596 :
1597 163 : if (opt_index < vm_args->nOptions) {
1598 : /* Get main-class argument. */
1599 :
1600 141 : mainname = vm_args->options[opt_index].optionString;
1601 :
1602 : /* If the main class argument is a jar file, put it into the
1603 : classpath. */
1604 :
1605 141 : if (opt_jar == true) {
1606 0 : char* p = MNEW(char, strlen(mainname) + strlen("0"));
1607 :
1608 0 : strcpy(p, mainname);
1609 :
1610 : #if defined(ENABLE_JAVASE)
1611 0 : VM::get_current()->get_properties().put("java.class.path", p);
1612 : #endif
1613 : }
1614 : else {
1615 : /* Replace dots with slashes in the class name. */
1616 :
1617 3955 : for (unsigned int i = 0; i < strlen(mainname); i++)
1618 3814 : if (mainname[i] == '.')
1619 20 : mainname[i] = '/';
1620 : }
1621 :
1622 : /* Move index to first argument. */
1623 :
1624 141 : opt_index++;
1625 : }
1626 :
1627 : /* Do we have a main-class argument? */
1628 :
1629 163 : if (mainname == NULL)
1630 22 : usage();
1631 :
1632 : #if !defined(NDEBUG)
1633 141 : if (opt_CompileMethod != NULL) {
1634 0 : vm_compile_method(mainname);
1635 : /* write logfiles */
1636 0 : write_logfiles();
1637 0 : return;
1638 : }
1639 : #endif
1640 :
1641 : /* Build argument array. */
1642 :
1643 141 : int32_t oalength = vm_args->nOptions - opt_index;
1644 :
1645 141 : ObjectArray oa(oalength, class_java_lang_String);
1646 :
1647 141 : if (oa.is_null())
1648 0 : vm_exit(1);
1649 :
1650 235 : for (int i = 0; i < oalength; i++) {
1651 94 : char* option = vm_args->options[opt_index + i].optionString;
1652 :
1653 94 : java_handle_t* s = JavaString::from_utf8(option);
1654 :
1655 94 : oa.set_element(i, s);
1656 : }
1657 :
1658 : /* set return value to OK */
1659 :
1660 141 : status = 0;
1661 :
1662 141 : if (opt_jar == true) {
1663 : /* open jar file with java.util.jar.JarFile */
1664 :
1665 0 : mainname = vm_get_mainclass_from_jar(mainname);
1666 :
1667 0 : if (mainname == NULL)
1668 0 : vm_exit(1);
1669 : }
1670 :
1671 : /* load the main class */
1672 :
1673 141 : Utf8String mainutf = Utf8String::from_utf8(mainname);
1674 :
1675 : #if defined(ENABLE_JAVAME_CLDC1_1)
1676 : classinfo* mainclass = load_class_bootstrap(mainutf);
1677 : #else
1678 141 : classinfo* mainclass = load_class_from_sysloader(mainutf);
1679 : #endif
1680 :
1681 : /* error loading class */
1682 :
1683 141 : java_handle_t* e = exceptions_get_and_clear_exception();
1684 :
1685 141 : if ((e != NULL) || (mainclass == NULL)) {
1686 0 : exceptions_throw_noclassdeffounderror_cause(e);
1687 0 : exceptions_print_stacktrace();
1688 0 : vm_exit(1);
1689 : }
1690 :
1691 141 : if (!link_class(mainclass)) {
1692 0 : exceptions_print_stacktrace();
1693 0 : vm_exit(1);
1694 : }
1695 :
1696 : /* find the `main' method of the main class */
1697 :
1698 : m = class_resolveclassmethod(mainclass,
1699 : Utf8String::from_utf8("main"),
1700 : Utf8String::from_utf8("([Ljava/lang/String;)V"),
1701 : class_java_lang_Object,
1702 141 : false);
1703 :
1704 141 : if (exceptions_get_exception()) {
1705 0 : exceptions_print_stacktrace();
1706 0 : vm_exit(1);
1707 : }
1708 :
1709 : /* there is no main method or it isn't static */
1710 :
1711 141 : if ((m == NULL) || !(m->flags & ACC_STATIC)) {
1712 0 : exceptions_clear_exception();
1713 : exceptions_throw_nosuchmethoderror(mainclass,
1714 : Utf8String::from_utf8("main"),
1715 0 : Utf8String::from_utf8("([Ljava/lang/String;)V"));
1716 :
1717 0 : exceptions_print_stacktrace();
1718 0 : vm_exit(1);
1719 : }
1720 :
1721 : #ifdef TYPEINFO_DEBUG_TEST
1722 : /* test the typeinfo system */
1723 : typeinfo_test();
1724 : #endif
1725 :
1726 : /* start the main thread */
1727 :
1728 141 : (void) vm_call_method(m, NULL, oa.get_handle());
1729 :
1730 : /* exception occurred? */
1731 :
1732 131 : if (exceptions_get_exception()) {
1733 41 : exceptions_print_stacktrace();
1734 41 : status = 1;
1735 : }
1736 :
1737 : /* Detach the main thread so that it appears to have ended when
1738 : the application's main method exits. */
1739 :
1740 131 : if (!thread_detach_current_thread())
1741 0 : os::abort("vm_run: Could not detach main thread.");
1742 :
1743 : /* write logfiles */
1744 131 : write_logfiles();
1745 :
1746 : /* Destroy the JavaVM. */
1747 :
1748 131 : (void) vm_destroy(vm);
1749 :
1750 : /* And exit. */
1751 :
1752 131 : vm_exit(status);
1753 : }
1754 :
1755 :
1756 : /* vm_destroy ******************************************************************
1757 :
1758 : Unloads a Java VM and reclaims its resources.
1759 :
1760 : *******************************************************************************/
1761 :
1762 131 : int vm_destroy(JavaVM *vm)
1763 : {
1764 : /* Create a a trivial new Java waiter thread called
1765 : "DestroyJavaVM". */
1766 :
1767 : JavaVMAttachArgs args;
1768 :
1769 131 : args.name = (char*) "DestroyJavaVM";
1770 131 : args.group = NULL;
1771 :
1772 131 : if (!thread_attach_current_thread(&args, false))
1773 0 : return 1;
1774 :
1775 : /* Wait until we are the last non-daemon thread. */
1776 :
1777 131 : threads_join_all_threads();
1778 :
1779 : // Hook point before the VM is actually destroyed.
1780 131 : Hook::vm_shutdown();
1781 :
1782 : /* VM is gone. */
1783 :
1784 : // _created = false;
1785 :
1786 : /* Everything is ok. */
1787 :
1788 131 : return 0;
1789 : }
1790 :
1791 :
1792 : /* vm_exit *********************************************************************
1793 :
1794 : Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1795 :
1796 : *******************************************************************************/
1797 :
1798 131 : void vm_exit(s4 status)
1799 : {
1800 : methodinfo *m;
1801 :
1802 : /* signal that we are exiting */
1803 :
1804 : // _exiting = true;
1805 :
1806 131 : assert(class_java_lang_System);
1807 131 : assert(class_java_lang_System->state & CLASS_LOADED);
1808 :
1809 : #if defined(ENABLE_JVMTI)
1810 : if (jvmti || (dbgcom!=NULL)) {
1811 : jvmti_set_phase(JVMTI_PHASE_DEAD);
1812 : if (jvmti) jvmti_agentunload();
1813 : }
1814 : #endif
1815 :
1816 131 : if (!link_class(class_java_lang_System)) {
1817 0 : exceptions_print_stacktrace();
1818 0 : exit(1);
1819 : }
1820 :
1821 : /* call java.lang.System.exit(I)V */
1822 :
1823 : m = class_resolveclassmethod(class_java_lang_System,
1824 : Utf8String::from_utf8("exit"),
1825 : utf8::int__void,
1826 : class_java_lang_Object,
1827 131 : true);
1828 :
1829 131 : if (m == NULL) {
1830 0 : exceptions_print_stacktrace();
1831 0 : exit(1);
1832 : }
1833 :
1834 : /* call the exit function with passed exit status */
1835 :
1836 131 : (void) vm_call_method(m, NULL, status);
1837 :
1838 : /* If we had an exception, just ignore the exception and exit with
1839 : the proper code. */
1840 :
1841 0 : vm_shutdown(status);
1842 0 : }
1843 :
1844 :
1845 : /* vm_shutdown *****************************************************************
1846 :
1847 : Terminates the system immediately without freeing memory explicitly
1848 : (to be used only for abnormal termination).
1849 :
1850 : *******************************************************************************/
1851 :
1852 141 : void vm_shutdown(s4 status)
1853 : {
1854 141 : if (opt_verbose
1855 : #if defined(ENABLE_STATISTICS)
1856 : || opt_getcompilingtime || opt_stat
1857 : #endif
1858 : )
1859 : {
1860 0 : log_text("CACAO terminated by shutdown");
1861 0 : dolog("Exit status: %d\n", (s4) status);
1862 :
1863 : }
1864 :
1865 : #if defined(ENABLE_JVMTI)
1866 : /* terminate cacaodbgserver */
1867 : if (dbgcom!=NULL) {
1868 : mutex_lock(&dbgcomlock);
1869 : dbgcom->running=1;
1870 : mutex_unlock(&dbgcomlock);
1871 : jvmti_cacaodbgserver_quit();
1872 : }
1873 : #endif
1874 :
1875 : #if defined(ENABLE_THREADS)
1876 141 : finalizer_join_thread();
1877 : #endif
1878 :
1879 141 : exit(status);
1880 : }
1881 :
1882 : #include "toolbox/OStream.hpp"
1883 :
1884 : /* vm_exit_handler *************************************************************
1885 :
1886 : The exit_handler function is called upon program termination.
1887 :
1888 : ATTENTION: Don't free system resources here! Some threads may still
1889 : be running as this is called from VMRuntime.exit(). The OS does the
1890 : cleanup for us.
1891 :
1892 : *******************************************************************************/
1893 :
1894 165 : void vm_exit_handler(void)
1895 : {
1896 : #if !defined(NDEBUG)
1897 165 : if (showmethods)
1898 0 : class_showmethods(mainclass);
1899 :
1900 165 : if (showconstantpool)
1901 0 : class_showconstantpool(mainclass);
1902 :
1903 : # if defined(ENABLE_PROFILING)
1904 : if (opt_prof)
1905 : profile_printstats();
1906 : # endif
1907 : #endif /* !defined(NDEBUG) */
1908 :
1909 : #if defined(ENABLE_CYCLES_STATS)
1910 : builtin_print_cycles_stats(log_get_logfile());
1911 : stacktrace_print_cycles_stats(log_get_logfile());
1912 : #endif
1913 :
1914 165 : if (opt_verbose
1915 : #if defined(ENABLE_STATISTICS)
1916 : || opt_getcompilingtime || opt_stat
1917 : #endif
1918 : )
1919 : {
1920 0 : log_text("CACAO terminated");
1921 :
1922 : #if 0 && defined(ENABLE_STATISTICS)
1923 : if (opt_stat) {
1924 : #ifdef TYPECHECK_STATISTICS
1925 : // XXX TYPECHECK_STATISTICS is currently not usable
1926 : typecheck_print_statistics(get_logfile());
1927 : #endif
1928 : }
1929 :
1930 : #endif /* defined(ENABLE_STATISTICS) */
1931 : }
1932 : /* vm_print_profile(stderr);*/
1933 165 : }
1934 :
1935 131 : static void write_logfiles() {
1936 : #if defined(ENABLE_RT_TIMING)
1937 : if (!opt_RtTimingLogfile) {
1938 : FILE *file = fopen("rt-timing.log", "w");
1939 : if (file == NULL)
1940 : /* fallback to stdout */
1941 : file = stdout;
1942 : opt_RtTimingLogfile = file;
1943 : }
1944 : {
1945 : assert(opt_RtTimingLogfile);
1946 : cacao::OStream OS(opt_RtTimingLogfile);
1947 : OS << "\nreal-time measurment:\n" << cacao::nl;
1948 : cacao::RTGroup::root().print(OS);
1949 : }
1950 : #endif
1951 :
1952 : #if defined(ENABLE_STATISTICS)
1953 : if (!opt_StatisticsLogfile) {
1954 : FILE *file = fopen("statistics.log", "w");
1955 : if (file == NULL)
1956 : /* fallback to stdout */
1957 : file = stdout;
1958 : opt_StatisticsLogfile = file;
1959 : }
1960 : {
1961 : assert(opt_StatisticsLogfile);
1962 : cacao::OStream OS(opt_StatisticsLogfile);
1963 : cacao::StatGroup::root().print(OS);
1964 : }
1965 : #endif
1966 :
1967 131 : }
1968 :
1969 : /* vm_abort_disassemble ********************************************************
1970 :
1971 : Prints an error message, disassemble the given code range (if
1972 : enabled) and aborts the VM.
1973 :
1974 : IN:
1975 : pc.......PC to disassemble
1976 : count....number of instructions to disassemble
1977 :
1978 : *******************************************************************************/
1979 :
1980 0 : void vm_abort_disassemble(void *pc, int count, const char *text, ...)
1981 : {
1982 : va_list ap;
1983 : #if defined(ENABLE_DISASSEMBLER)
1984 : int i;
1985 : #endif
1986 :
1987 : /* Print debug message. */
1988 :
1989 0 : log_start();
1990 :
1991 0 : va_start(ap, text);
1992 0 : log_vprint(text, ap);
1993 0 : va_end(ap);
1994 :
1995 0 : log_finish();
1996 :
1997 : /* Print the PC. */
1998 :
1999 0 : log_println("PC=0x%0" PRINTF_INTPTR_NUM_HEXDIGITS PRIxPTR, (intptr_t) pc);
2000 :
2001 : #if defined(ENABLE_DISASSEMBLER)
2002 : log_println("machine instructions at PC:");
2003 :
2004 : /* Disassemble the given number of instructions. */
2005 :
2006 : for (i = 0; i < count; i++)
2007 : // FIXME disassinstr should use void*.
2008 : pc = disassinstr((u1*) pc);
2009 : #endif
2010 :
2011 0 : os::abort("Aborting...");
2012 0 : }
2013 :
2014 :
2015 : /* vm_get_mainclass_from_jar ***************************************************
2016 :
2017 : Gets the name of the main class from a JAR's manifest file.
2018 :
2019 : *******************************************************************************/
2020 :
2021 0 : static char *vm_get_mainclass_from_jar(char *mainname)
2022 : {
2023 : classinfo *c;
2024 : java_handle_t *o;
2025 : methodinfo *m;
2026 : java_handle_t *s;
2027 :
2028 : #if defined(ENABLE_JAVAME_CLDC1_1)
2029 : c = load_class_bootstrap(Utf8String::from_utf8("java/util/jar/JarFile"));
2030 : #else
2031 0 : c = load_class_from_sysloader(Utf8String::from_utf8("java/util/jar/JarFile"));
2032 : #endif
2033 :
2034 0 : if (c == NULL) {
2035 0 : exceptions_print_stacktrace();
2036 0 : return NULL;
2037 : }
2038 :
2039 : /* create JarFile object */
2040 :
2041 0 : o = builtin_new(c);
2042 :
2043 0 : if (o == NULL) {
2044 0 : exceptions_print_stacktrace();
2045 0 : return NULL;
2046 : }
2047 :
2048 : m = class_resolveclassmethod(c,
2049 : utf8::init,
2050 : utf8::java_lang_String__void,
2051 : class_java_lang_Object,
2052 0 : true);
2053 :
2054 0 : if (m == NULL) {
2055 0 : exceptions_print_stacktrace();
2056 0 : return NULL;
2057 : }
2058 :
2059 0 : s = JavaString::from_utf8(mainname);
2060 :
2061 0 : (void) vm_call_method(m, o, s);
2062 :
2063 0 : if (exceptions_get_exception()) {
2064 0 : exceptions_print_stacktrace();
2065 0 : return NULL;
2066 : }
2067 :
2068 : /* get manifest object */
2069 :
2070 : m = class_resolveclassmethod(c,
2071 : Utf8String::from_utf8("getManifest"),
2072 : Utf8String::from_utf8("()Ljava/util/jar/Manifest;"),
2073 : class_java_lang_Object,
2074 0 : true);
2075 :
2076 0 : if (m == NULL) {
2077 0 : exceptions_print_stacktrace();
2078 0 : return NULL;
2079 : }
2080 :
2081 0 : o = vm_call_method(m, o);
2082 :
2083 0 : if (o == NULL) {
2084 0 : fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainname);
2085 0 : return NULL;
2086 : }
2087 :
2088 :
2089 : /* get Main Attributes */
2090 :
2091 0 : LLNI_class_get(o, c);
2092 :
2093 : m = class_resolveclassmethod(c,
2094 : Utf8String::from_utf8("getMainAttributes"),
2095 : Utf8String::from_utf8("()Ljava/util/jar/Attributes;"),
2096 : class_java_lang_Object,
2097 0 : true);
2098 :
2099 0 : if (m == NULL) {
2100 0 : exceptions_print_stacktrace();
2101 0 : return NULL;
2102 : }
2103 :
2104 0 : o = vm_call_method(m, o);
2105 :
2106 0 : if (o == NULL) {
2107 0 : fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainname);
2108 0 : return NULL;
2109 : }
2110 :
2111 :
2112 : /* get property Main-Class */
2113 :
2114 0 : LLNI_class_get(o, c);
2115 :
2116 : m = class_resolveclassmethod(c,
2117 : Utf8String::from_utf8("getValue"),
2118 : Utf8String::from_utf8("(Ljava/lang/String;)Ljava/lang/String;"),
2119 : class_java_lang_Object,
2120 0 : true);
2121 :
2122 0 : if (m == NULL) {
2123 0 : exceptions_print_stacktrace();
2124 0 : return NULL;
2125 : }
2126 :
2127 0 : s = JavaString::from_utf8("Main-Class");
2128 :
2129 0 : o = vm_call_method(m, o, s);
2130 :
2131 0 : if (o == NULL) {
2132 0 : fprintf(stderr, "Failed to load Main-Class manifest attribute from\n");
2133 0 : fprintf(stderr, "%s\n", mainname);
2134 0 : return NULL;
2135 : }
2136 :
2137 0 : return JavaString(o).to_chars();
2138 : }
2139 :
2140 :
2141 : /* vm_compile_all **************************************************************
2142 :
2143 : Compile all methods found in the bootclasspath.
2144 :
2145 : *******************************************************************************/
2146 :
2147 : #if !defined(NDEBUG)
2148 0 : static void vm_compile_all(void)
2149 : {
2150 : classinfo *c;
2151 : methodinfo *m;
2152 : u4 slot;
2153 : classcache_name_entry *nmen;
2154 : classcache_class_entry *clsen;
2155 : s4 i;
2156 :
2157 : /* create all classes found in the bootclasspath */
2158 : /* XXX currently only works with zip/jar's */
2159 :
2160 0 : loader_load_all_classes();
2161 :
2162 : /* link all classes */
2163 :
2164 0 : for (slot = 0; slot < hashtable_classcache.size; slot++) {
2165 0 : nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
2166 :
2167 0 : for (; nmen; nmen = nmen->hashlink) {
2168 : /* iterate over all class entries */
2169 :
2170 0 : for (clsen = nmen->classes; clsen; clsen = clsen->next) {
2171 0 : c = clsen->classobj;
2172 :
2173 0 : if (c == NULL)
2174 0 : continue;
2175 :
2176 0 : if (!(c->state & CLASS_LINKED)) {
2177 0 : if (!link_class(c)) {
2178 0 : fprintf(stderr, "Error linking: ");
2179 0 : utf_fprint_printable_ascii_classname(stderr, c->name);
2180 0 : fprintf(stderr, "\n");
2181 :
2182 : /* print out exception and cause */
2183 :
2184 0 : exceptions_print_current_exception();
2185 :
2186 : /* goto next class */
2187 :
2188 0 : continue;
2189 : }
2190 : }
2191 :
2192 : /* compile all class methods */
2193 :
2194 0 : for (i = 0; i < c->methodscount; i++) {
2195 0 : m = &(c->methods[i]);
2196 :
2197 0 : if (m->jcode != NULL) {
2198 0 : if (!jit_compile(m)) {
2199 0 : fprintf(stderr, "Error compiling: ");
2200 0 : utf_fprint_printable_ascii_classname(stderr, c->name);
2201 0 : fprintf(stderr, ".");
2202 0 : utf_fprint_printable_ascii(stderr, m->name);
2203 0 : utf_fprint_printable_ascii(stderr, m->descriptor);
2204 0 : fprintf(stderr, "\n");
2205 :
2206 : /* print out exception and cause */
2207 :
2208 0 : exceptions_print_current_exception();
2209 : }
2210 : }
2211 : }
2212 : }
2213 : }
2214 : }
2215 0 : }
2216 : #endif /* !defined(NDEBUG) */
2217 :
2218 :
2219 : /* vm_compile_method ***********************************************************
2220 :
2221 : Compile a specific method.
2222 :
2223 : *******************************************************************************/
2224 :
2225 : #if !defined(NDEBUG)
2226 0 : static void vm_compile_method(char* mainname)
2227 : {
2228 : methodinfo *m;
2229 :
2230 : /* create, load and link the main class */
2231 :
2232 0 : mainclass = load_class_bootstrap(Utf8String::from_utf8(mainname));
2233 :
2234 0 : if (mainclass == NULL)
2235 0 : exceptions_print_stacktrace();
2236 :
2237 0 : if (!link_class(mainclass))
2238 0 : exceptions_print_stacktrace();
2239 :
2240 0 : if (opt_CompileSignature != NULL) {
2241 : m = class_resolveclassmethod(mainclass,
2242 : Utf8String::from_utf8(opt_CompileMethod),
2243 : Utf8String::from_utf8(opt_CompileSignature),
2244 : mainclass,
2245 0 : false);
2246 : }
2247 : else {
2248 : m = class_resolveclassmethod(mainclass,
2249 : Utf8String::from_utf8(opt_CompileMethod),
2250 : NULL,
2251 : mainclass,
2252 0 : false);
2253 : }
2254 :
2255 0 : if (m == NULL)
2256 : os::abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
2257 0 : opt_CompileMethod, opt_CompileSignature ? opt_CompileSignature : "");
2258 :
2259 0 : jit_compile(m);
2260 0 : }
2261 : #endif /* !defined(NDEBUG) */
2262 :
2263 :
2264 : /* vm_call_array ***************************************************************
2265 :
2266 : Calls a Java method with a variable number of arguments, passed via
2267 : an argument array.
2268 :
2269 : ATTENTION: This function has to be used outside the nativeworld.
2270 :
2271 : *******************************************************************************/
2272 :
2273 : #define VM_CALL_ARRAY(name, type) \
2274 : static type vm_call##name##_array(methodinfo *m, uint64_t *array) \
2275 : { \
2276 : methoddesc *md; \
2277 : void *pv; \
2278 : type value; \
2279 : \
2280 : assert(m->code != NULL); \
2281 : \
2282 : md = m->parseddesc; \
2283 : pv = m->code->entrypoint; \
2284 : \
2285 : STATISTICS(count_calls_native_to_java++); \
2286 : \
2287 : value = asm_vm_call_method##name(pv, array, md->memuse); \
2288 : \
2289 : return value; \
2290 : }
2291 :
2292 359931 : static java_handle_t *vm_call_array(methodinfo *m, uint64_t *array)
2293 : {
2294 : methoddesc *md;
2295 : void *pv;
2296 : java_object_t *o;
2297 :
2298 359931 : assert(m->code != NULL);
2299 :
2300 359931 : md = m->parseddesc;
2301 359931 : pv = m->code->entrypoint;
2302 :
2303 : STATISTICS(count_calls_native_to_java++);
2304 :
2305 359931 : o = asm_vm_call_method(pv, array, md->memuse);
2306 :
2307 359785 : if (md->returntype.type == TYPE_VOID)
2308 66592 : o = NULL;
2309 :
2310 359785 : return LLNI_WRAP(o);
2311 : }
2312 :
2313 381295 : VM_CALL_ARRAY(_int, int32_t)
2314 6 : VM_CALL_ARRAY(_long, int64_t)
2315 7 : VM_CALL_ARRAY(_float, float)
2316 7 : VM_CALL_ARRAY(_double, double)
2317 :
2318 :
2319 : /* vm_call_method **************************************************************
2320 :
2321 : Calls a Java method with a variable number of arguments.
2322 :
2323 : *******************************************************************************/
2324 :
2325 : #define VM_CALL_METHOD(name, type) \
2326 : type vm_call_##name(methodinfo *m, java_handle_t *o, ...) \
2327 : { \
2328 : va_list ap; \
2329 : type value; \
2330 : \
2331 : va_start(ap, o); \
2332 : value = vm_call_##name##_valist(m, o, ap); \
2333 : va_end(ap); \
2334 : \
2335 : return value; \
2336 : }
2337 :
2338 74519 : VM_CALL_METHOD(method, java_handle_t *)
2339 12 : VM_CALL_METHOD(method_int, int32_t)
2340 0 : VM_CALL_METHOD(method_long, int64_t)
2341 0 : VM_CALL_METHOD(method_float, float)
2342 0 : VM_CALL_METHOD(method_double, double)
2343 :
2344 :
2345 : /* vm_call_method_valist *******************************************************
2346 :
2347 : Calls a Java method with a variable number of arguments, passed via
2348 : a va_list.
2349 :
2350 : *******************************************************************************/
2351 :
2352 : #define VM_CALL_METHOD_VALIST(name, type) \
2353 : type vm_call_method##name##valist(methodinfo *m, java_handle_t *o, \
2354 : va_list ap) \
2355 : { \
2356 : uint64_t *array; \
2357 : type value; \
2358 : \
2359 : if (m->code == NULL) \
2360 : if (!jit_compile(m)) \
2361 : return 0; \
2362 : \
2363 : THREAD_NATIVEWORLD_EXIT; \
2364 : \
2365 : DumpMemoryArea dma; \
2366 : \
2367 : array = argument_vmarray_from_valist(m, o, ap); \
2368 : value = vm_call##name##array(m, array); \
2369 : \
2370 : THREAD_NATIVEWORLD_ENTER; \
2371 : \
2372 : return value; \
2373 : }
2374 :
2375 359171 : VM_CALL_METHOD_VALIST(_, java_handle_t *)
2376 381237 : VM_CALL_METHOD_VALIST(_int_, int32_t)
2377 0 : VM_CALL_METHOD_VALIST(_long_, int64_t)
2378 0 : VM_CALL_METHOD_VALIST(_float_, float)
2379 0 : VM_CALL_METHOD_VALIST(_double_, double)
2380 :
2381 :
2382 : /* vm_call_method_jvalue *******************************************************
2383 :
2384 : Calls a Java method with a variable number of arguments, passed via
2385 : a jvalue array.
2386 :
2387 : *******************************************************************************/
2388 :
2389 : #define VM_CALL_METHOD_JVALUE(name, type) \
2390 : type vm_call_method##name##jvalue(methodinfo *m, java_handle_t *o, \
2391 : const jvalue *args) \
2392 : { \
2393 : uint64_t *array; \
2394 : type value; \
2395 : \
2396 : if (m->code == NULL) \
2397 : if (!jit_compile(m)) \
2398 : return 0; \
2399 : \
2400 : THREAD_NATIVEWORLD_EXIT; \
2401 : \
2402 : DumpMemoryArea dma; \
2403 : \
2404 : array = argument_vmarray_from_jvalue(m, o, args); \
2405 : value = vm_call##name##array(m, array); \
2406 : \
2407 : THREAD_NATIVEWORLD_ENTER; \
2408 : \
2409 : return value; \
2410 : }
2411 :
2412 0 : VM_CALL_METHOD_JVALUE(_, java_handle_t *)
2413 0 : VM_CALL_METHOD_JVALUE(_int_, int32_t)
2414 0 : VM_CALL_METHOD_JVALUE(_long_, int64_t)
2415 0 : VM_CALL_METHOD_JVALUE(_float_, float)
2416 0 : VM_CALL_METHOD_JVALUE(_double_, double)
2417 :
2418 :
2419 : /* vm_call_method_objectarray **************************************************
2420 :
2421 : Calls a Java method with a variable number if arguments, passed via
2422 : an objectarray of boxed values. Returns a boxed value.
2423 :
2424 : *******************************************************************************/
2425 :
2426 853 : java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o,
2427 : java_handle_objectarray_t *params)
2428 : {
2429 : uint64_t *array;
2430 : java_handle_t *xptr;
2431 : java_handle_t *ro;
2432 : imm_union value;
2433 :
2434 : /* Prevent compiler warnings. */
2435 :
2436 853 : ro = NULL;
2437 :
2438 : /* compile methods which are not yet compiled */
2439 :
2440 853 : if (m->code == NULL)
2441 281 : if (!jit_compile(m))
2442 0 : return NULL;
2443 :
2444 : /* leave the nativeworld */
2445 :
2446 : THREAD_NATIVEWORLD_EXIT;
2447 :
2448 : // Create new dump memory area.
2449 853 : DumpMemoryArea dma;
2450 :
2451 : /* Fill the argument array from a object-array. */
2452 :
2453 853 : array = argument_vmarray_from_objectarray(m, o, params);
2454 :
2455 853 : if (array == NULL) {
2456 : /* enter the nativeworld again */
2457 :
2458 : THREAD_NATIVEWORLD_ENTER;
2459 :
2460 0 : exceptions_throw_illegalargumentexception();
2461 :
2462 0 : return NULL;
2463 : }
2464 :
2465 853 : switch (m->parseddesc->returntype.primitivetype) {
2466 : case PRIMITIVETYPE_VOID:
2467 499 : value.a = vm_call_array(m, array);
2468 499 : break;
2469 :
2470 : case PRIMITIVETYPE_BOOLEAN:
2471 : case PRIMITIVETYPE_BYTE:
2472 : case PRIMITIVETYPE_CHAR:
2473 : case PRIMITIVETYPE_SHORT:
2474 : case PRIMITIVETYPE_INT:
2475 58 : value.i = vm_call_int_array(m, array);
2476 58 : break;
2477 :
2478 : case PRIMITIVETYPE_LONG:
2479 6 : value.l = vm_call_long_array(m, array);
2480 6 : break;
2481 :
2482 : case PRIMITIVETYPE_FLOAT:
2483 7 : value.f = vm_call_float_array(m, array);
2484 7 : break;
2485 :
2486 : case PRIMITIVETYPE_DOUBLE:
2487 7 : value.d = vm_call_double_array(m, array);
2488 7 : break;
2489 :
2490 : case TYPE_ADR:
2491 276 : ro = vm_call_array(m, array);
2492 276 : break;
2493 :
2494 : default:
2495 0 : os::abort("vm_call_method_objectarray: invalid return type %d", m->parseddesc->returntype.primitivetype);
2496 : }
2497 :
2498 : /* enter the nativeworld again */
2499 :
2500 : THREAD_NATIVEWORLD_ENTER;
2501 :
2502 : /* box the return value if necesarry */
2503 :
2504 853 : if (m->parseddesc->returntype.primitivetype != (PrimitiveType) TYPE_ADR)
2505 577 : ro = Primitive::box(m->parseddesc->returntype.primitivetype, value);
2506 :
2507 : /* check for an exception */
2508 :
2509 853 : xptr = exceptions_get_exception();
2510 :
2511 853 : if (xptr != NULL) {
2512 : /* clear exception pointer, we are calling JIT code again */
2513 :
2514 11 : exceptions_clear_exception();
2515 :
2516 11 : exceptions_throw_invocationtargetexception(xptr);
2517 : }
2518 :
2519 853 : return ro;
2520 : }
2521 :
2522 :
2523 : /* Legacy C interface *********************************************************/
2524 :
2525 : extern "C" {
2526 :
2527 0 : JNIEnv* VM_get_jnienv() { return VM::get_current()->get_jnienv(); }
2528 :
2529 0 : void vm_abort(const char* text, ...)
2530 : {
2531 : va_list ap;
2532 :
2533 0 : log_println("vm_abort: WARNING, port me to C++ and use os::abort() instead.");
2534 :
2535 : // Print the log message.
2536 0 : log_start();
2537 :
2538 0 : va_start(ap, text);
2539 0 : log_vprint(text, ap);
2540 0 : va_end(ap);
2541 :
2542 0 : log_finish();
2543 :
2544 : // Print a backtrace.
2545 0 : os::print_backtrace();
2546 :
2547 : // Now abort the VM.
2548 0 : os::abort();
2549 0 : }
2550 :
2551 : }
2552 :
2553 :
2554 : /*
2555 : * These are local overrides for various environment variables in Emacs.
2556 : * Please do not remove this and leave it at the end of the file, where
2557 : * Emacs will automagically detect them.
2558 : * ---------------------------------------------------------------------
2559 : * Local variables:
2560 : * mode: c++
2561 : * indent-tabs-mode: t
2562 : * c-basic-offset: 4
2563 : * tab-width: 4
2564 : * End:
2565 : * vim:noexpandtab:sw=4:ts=4:
2566 : */
|