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 :
567 : #if !defined(NDEBUG)
568 : #define COMPILE_METHOD
569 : #else
570 : #define COMPILE_METHOD
571 : #endif
572 :
573 : #if defined(COMPILE_METHOD)
574 : static void vm_compile_method(char* mainname);
575 : #endif
576 :
577 : #if !defined(NDEBUG)
578 : static void vm_compile_all(void);
579 : #endif
580 :
581 : /**
582 : * Implementation for JNI_CreateJavaVM. This function creates a VM
583 : * object.
584 : *
585 : * @param p_vm
586 : * @param p_env
587 : * @param vm_args
588 : *
589 : * @return true on success, false otherwise.
590 : */
591 165 : bool VM::create(JavaVM** p_vm, void** p_env, void* vm_args)
592 : {
593 : JavaVMInitArgs* _vm_args;
594 :
595 : // Get the arguments for the new JVM.
596 165 : _vm_args = (JavaVMInitArgs *) vm_args;
597 :
598 : // Instantiate a new VM.
599 : try {
600 165 : _vm = new VM(_vm_args);
601 : }
602 0 : catch (std::exception e) {
603 : // FIXME How can we delete the resources allocated?
604 : // /* release allocated memory */
605 : // FREE(env, _Jv_JNIEnv);
606 : // FREE(vm, _Jv_JavaVM);
607 :
608 0 : _vm = NULL;
609 :
610 0 : return false;
611 : }
612 :
613 : // Return the values.
614 :
615 163 : *p_vm = _vm->get_javavm();
616 163 : *p_env = _vm->get_jnienv();
617 :
618 163 : return true;
619 : }
620 :
621 :
622 : /**
623 : * C wrapper for VM::create.
624 : */
625 : extern "C" {
626 165 : bool VM_create(JavaVM** p_vm, void** p_env, void* vm_args)
627 : {
628 165 : return VM::create(p_vm, p_env, vm_args);
629 : }
630 : }
631 :
632 :
633 : /**
634 : * VM constructor.
635 : */
636 165 : VM::VM(JavaVMInitArgs* vm_args)
637 : {
638 : // Very first thing to do: we are initializing.
639 165 : _initializing = true;
640 :
641 : // Make sure logging works
642 :
643 :
644 : // Make ourself globally visible.
645 : // XXX Is this a good idea?
646 165 : _vm = this;
647 :
648 : /* create and fill a JavaVM structure */
649 :
650 165 : _javavm = new JavaVM();
651 :
652 : #if defined(ENABLE_JNI)
653 165 : _javavm->functions = &_Jv_JNIInvokeInterface;
654 : #endif
655 :
656 : /* get the VM and Env tables (must be set before vm_create) */
657 : /* XXX JVMTI Agents needs a JavaVM */
658 :
659 165 : _jnienv = new JNIEnv();
660 :
661 : #if defined(ENABLE_JNI)
662 165 : _jnienv->functions = &_Jv_JNINativeInterface;
663 : #endif
664 :
665 : /* actually create the JVM */
666 :
667 165 : int len = 0;
668 : char *p;
669 : char *boot_class_path;
670 165 : char *boot_class_path_p = NULL;
671 : char *class_path;
672 : int opt;
673 : bool opt_version;
674 : bool opt_exit;
675 :
676 : #if defined(ENABLE_JNI)
677 : /* Check the JNI version requested. */
678 :
679 165 : if (!jni_version_check(vm_args->version))
680 0 : throw std::exception();
681 : #endif
682 :
683 : /* We only support 1 JVM instance. */
684 :
685 165 : if (vms > 0)
686 0 : throw std::exception();
687 :
688 : /* Install the exit handler. */
689 :
690 165 : if (atexit(vm_exit_handler))
691 0 : os::abort("atexit failed: %s\n", strerror(errno));
692 :
693 : /* Set some options. */
694 :
695 165 : opt_version = false;
696 165 : opt_exit = false;
697 :
698 165 : opt_heapmaxsize = HEAP_MAXSIZE;
699 165 : opt_heapstartsize = HEAP_STARTSIZE;
700 165 : opt_stacksize = STACK_SIZE;
701 :
702 : // First of all, parse the -XX options.
703 165 : options_xx(vm_args);
704 :
705 : // After -XX options are parsed, print the build-time
706 : // configuration, if requested.
707 165 : if (opt_PrintConfig)
708 22 : print_build_time_config();
709 :
710 : /* We need to check if the actual size of a java.lang.Class object
711 : is smaller or equal than the assumption made in
712 : src/vm/class.hpp. */
713 :
714 : // FIXME We need to check the size of java.lang.Class!!!
715 : // if (sizeof(java_lang_Class) > sizeof(dummy_java_lang_Class))
716 : // vm_abort("vm_create: java_lang_Class structure is bigger than classinfo.object (%d > %d)", sizeof(java_lang_Class), sizeof(dummy_java_lang_Class));
717 :
718 : /* set the VM starttime */
719 :
720 165 : _starttime = builtin_currenttimemillis();
721 :
722 : /* iterate over all passed options */
723 :
724 568 : while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
725 240 : switch (opt) {
726 : case OPT_FOO:
727 0 : opt_foo = true;
728 0 : break;
729 :
730 : case OPT_IGNORE:
731 0 : break;
732 :
733 : case OPT_JAR:
734 0 : opt_jar = true;
735 0 : break;
736 :
737 : case OPT_D32:
738 : #if SIZEOF_VOID_P == 8
739 0 : puts("Running a 32-bit JVM is not supported on this platform.");
740 0 : exit(1);
741 : #endif
742 : break;
743 :
744 : case OPT_D64:
745 : #if SIZEOF_VOID_P == 4
746 : puts("Running a 64-bit JVM is not supported on this platform.");
747 : exit(1);
748 : #endif
749 0 : break;
750 :
751 : case OPT_CLASSPATH:
752 : /* Forget old classpath and set the argument as new
753 : classpath. */
754 :
755 : // FIXME Make class_path const char*.
756 5 : class_path = (char*) _properties.get("java.class.path");
757 :
758 5 : p = MNEW(char, strlen(opt_arg) + strlen("0"));
759 :
760 5 : strcpy(p, opt_arg);
761 :
762 : #if defined(ENABLE_JAVASE)
763 5 : _properties.put("java.class.path", p);
764 : #endif
765 :
766 5 : MFREE(class_path, char, strlen(class_path));
767 5 : break;
768 :
769 : case OPT_D:
770 19 : for (unsigned int i = 0; i < strlen(opt_arg); i++) {
771 19 : if (opt_arg[i] == '=') {
772 1 : opt_arg[i] = '\0';
773 1 : _properties.put(opt_arg, opt_arg + i + 1);
774 1 : goto opt_d_done;
775 : }
776 : }
777 :
778 : /* if no '=' is given, just create an empty property */
779 :
780 0 : _properties.put(opt_arg, "");
781 :
782 : opt_d_done:
783 1 : break;
784 :
785 : case OPT_BOOTCLASSPATH:
786 : /* Forget default bootclasspath and set the argument as
787 : new boot classpath. */
788 :
789 : /* Forget stored -Xbootclasspath/p value */
790 165 : if (boot_class_path_p != NULL) {
791 0 : MFREE(boot_class_path_p, char, len);
792 0 : boot_class_path_p = NULL;
793 : }
794 : // FIXME Make boot_class_path const char*.
795 165 : boot_class_path = (char*) _properties.get("sun.boot.class.path");
796 :
797 165 : p = MNEW(char, strlen(opt_arg) + strlen("0"));
798 :
799 165 : strcpy(p, opt_arg);
800 :
801 165 : _properties.put("sun.boot.class.path", p);
802 165 : _properties.put("java.boot.class.path", p);
803 :
804 165 : MFREE(boot_class_path, char, strlen(boot_class_path));
805 165 : break;
806 :
807 : case OPT_BOOTCLASSPATH_A:
808 : /* Append to bootclasspath. */
809 :
810 : // FIXME Make boot_class_path const char*.
811 1 : boot_class_path = (char*) _properties.get("sun.boot.class.path");
812 :
813 1 : len = strlen(boot_class_path);
814 :
815 : // XXX (char*) quick hack
816 : p = (char*) MREALLOC(boot_class_path,
817 : char,
818 : len + strlen("0"),
819 : len + strlen(":") +
820 1 : strlen(opt_arg) + strlen("0"));
821 :
822 1 : strcat(p, ":");
823 1 : strcat(p, opt_arg);
824 :
825 1 : _properties.put("sun.boot.class.path", p);
826 1 : _properties.put("java.boot.class.path", p);
827 1 : break;
828 :
829 : case OPT_BOOTCLASSPATH_P:
830 : /* Prepend to bootclasspath. */
831 : /* Note: we can not add this value directly to sun/java.boot.class.path
832 : because we need to take care of the ordering regarding the
833 : endorseddirs property */
834 :
835 0 : if (boot_class_path_p == NULL) {
836 0 : boot_class_path_p = MNEW(char, strlen(opt_arg) + strlen("0"));
837 0 : strcpy(boot_class_path_p, opt_arg);
838 : } else {
839 0 : len = strlen(boot_class_path_p);
840 0 : p = MNEW(char, strlen(opt_arg) + strlen(":") + len + strlen("0"));
841 0 : strcpy(p, opt_arg);
842 0 : strcat(p, ":");
843 0 : strcat(p, boot_class_path_p);
844 0 : MFREE(boot_class_path_p, char, len);
845 0 : boot_class_path_p = p;
846 : }
847 0 : break;
848 :
849 : case OPT_BOOTCLASSPATH_C:
850 : /* Use as Java core library, but prepend VM interface
851 : classes. */
852 :
853 : // FIXME Make boot_class_path const char*.
854 0 : boot_class_path = (char*) _properties.get("sun.boot.class.path");
855 :
856 : len =
857 : strlen(CACAO_VM_ZIP) +
858 : strlen(":") +
859 : strlen(opt_arg) +
860 0 : strlen("0");
861 :
862 0 : p = MNEW(char, len);
863 :
864 0 : strcpy(p, CACAO_VM_ZIP);
865 0 : strcat(p, ":");
866 0 : strcat(p, opt_arg);
867 :
868 0 : _properties.put("sun.boot.class.path", p);
869 0 : _properties.put("java.boot.class.path", p);
870 :
871 0 : MFREE(boot_class_path, char, strlen(boot_class_path));
872 0 : break;
873 :
874 : #if defined(ENABLE_JVMTI)
875 : case OPT_AGENTLIB:
876 : // Parse option argument.
877 : p = strchr(opt_arg, '=');
878 : if (p != NULL)
879 : *(p++) = '\0';
880 :
881 : _nativeagents.register_agent_library(opt_arg, p);
882 : break;
883 :
884 : case OPT_AGENTPATH:
885 : // Parse option argument.
886 : p = strchr(opt_arg, '=');
887 : if (p != NULL)
888 : *(p++) = '\0';
889 :
890 : _nativeagents.register_agent_path(opt_arg, p);
891 : break;
892 :
893 : case OPT_RUN:
894 : // Parse option argument.
895 : p = strchr(opt_arg, ':');
896 : if (p != NULL)
897 : *(p++) = '\0';
898 :
899 : _nativeagents.register_agent_library(opt_arg, p);
900 : break;
901 : #endif
902 :
903 : case OPT_MX:
904 : case OPT_MS:
905 : case OPT_SS:
906 : {
907 : char c;
908 : int j;
909 :
910 0 : c = opt_arg[strlen(opt_arg) - 1];
911 :
912 0 : if ((c == 'k') || (c == 'K')) {
913 0 : j = atoi(opt_arg) * 1024;
914 :
915 0 : } else if ((c == 'm') || (c == 'M')) {
916 0 : j = atoi(opt_arg) * 1024 * 1024;
917 :
918 : } else
919 0 : j = atoi(opt_arg);
920 :
921 0 : if (opt == OPT_MX)
922 0 : opt_heapmaxsize = j;
923 0 : else if (opt == OPT_MS)
924 0 : opt_heapstartsize = j;
925 : else
926 0 : opt_stacksize = j;
927 : }
928 0 : break;
929 :
930 : case OPT_XCHECK_JNI:
931 : // HotSpot compatibility option.
932 0 : break;
933 :
934 : case OPT_VERBOSE1:
935 0 : opt_verbose = true;
936 0 : break;
937 :
938 : case OPT_VERBOSE:
939 0 : if (strcmp("class", opt_arg) == 0) {
940 0 : opt_verboseclass = true;
941 : }
942 0 : else if (strcmp("gc", opt_arg) == 0) {
943 0 : opt_verbosegc = true;
944 : }
945 0 : else if (strcmp("jni", opt_arg) == 0) {
946 0 : opt_verbosejni = true;
947 : }
948 : #if !defined(NDEBUG)
949 0 : else if (strcmp("jit", opt_arg) == 0) {
950 0 : opt_verbose = true;
951 0 : loadverbose = true;
952 0 : initverbose = true;
953 0 : compileverbose = true;
954 : }
955 : #endif
956 : else {
957 0 : printf("Unknown -verbose option: %s\n", opt_arg);
958 0 : usage();
959 : }
960 0 : break;
961 :
962 : case OPT_DEBUGCOLOR:
963 0 : opt_debugcolor = true;
964 0 : break;
965 :
966 : #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
967 : case OPT_VERBOSETC:
968 : opt_typecheckverbose = true;
969 : break;
970 : #endif
971 :
972 : case OPT_VERSION:
973 0 : opt_version = true;
974 0 : opt_exit = true;
975 0 : break;
976 :
977 : case OPT_FULLVERSION:
978 0 : fullversion();
979 0 : break;
980 :
981 : case OPT_SHOWVERSION:
982 0 : opt_version = true;
983 0 : break;
984 :
985 : #if defined(ENABLE_VERIFIER)
986 : case OPT_XVERIFY_ALL:
987 0 : opt_verify = true;
988 0 : break;
989 :
990 : case OPT_NOVERIFY:
991 : case OPT_XVERIFY_NONE:
992 0 : opt_verify = false;
993 0 : break;
994 : #endif
995 :
996 : #if defined(ENABLE_STATISTICS)
997 : case OPT_TIME:
998 : opt_getcompilingtime = true;
999 : opt_getloadingtime = true;
1000 : break;
1001 :
1002 : case OPT_STAT:
1003 : opt_stat = true;
1004 : break;
1005 : #endif
1006 :
1007 : case OPT_LOG:
1008 0 : log_init(opt_arg);
1009 0 : break;
1010 :
1011 : case OPT_CHECK:
1012 0 : for (unsigned int i = 0; i < strlen(opt_arg); i++) {
1013 0 : switch (opt_arg[i]) {
1014 : case 'b':
1015 0 : checkbounds = false;
1016 0 : break;
1017 : case 's':
1018 0 : checksync = false;
1019 0 : break;
1020 : default:
1021 0 : usage();
1022 : }
1023 : }
1024 0 : break;
1025 :
1026 : case OPT_LOAD:
1027 0 : opt_run = false;
1028 0 : makeinitializations = false;
1029 0 : break;
1030 :
1031 : case OPT_SHOW: /* Display options */
1032 4 : for (unsigned int i = 0; i < strlen(opt_arg); i++) {
1033 4 : switch (opt_arg[i]) {
1034 : case 'c':
1035 0 : showconstantpool = true;
1036 0 : break;
1037 :
1038 : case 'u':
1039 0 : showutf = true;
1040 0 : break;
1041 :
1042 : case 'm':
1043 0 : showmethods = true;
1044 0 : break;
1045 :
1046 : case 'i':
1047 2 : opt_showintermediate = true;
1048 2 : compileverbose = true;
1049 2 : break;
1050 :
1051 : #if defined(ENABLE_DISASSEMBLER)
1052 : case 'a':
1053 : opt_showdisassemble = true;
1054 : compileverbose = true;
1055 : break;
1056 : #endif
1057 :
1058 : case 'd':
1059 0 : opt_showddatasegment = true;
1060 0 : break;
1061 :
1062 : default:
1063 2 : usage();
1064 : }
1065 : }
1066 0 : break;
1067 :
1068 : #if defined(ENABLE_LOOP)
1069 : case OPT_OLOOP:
1070 : opt_loops = true;
1071 : break;
1072 : #endif
1073 :
1074 : #if defined(ENABLE_IFCONV)
1075 : case OPT_IFCONV:
1076 0 : opt_ifconv = true;
1077 0 : break;
1078 : #endif
1079 :
1080 : #if defined(ENABLE_LSRA)
1081 : case OPT_LSRA:
1082 : opt_lsra = true;
1083 : break;
1084 : #endif
1085 : #if defined(ENABLE_SSA)
1086 : case OPT_LSRA:
1087 : opt_lsra = true;
1088 : for (unsigned int i = 0; i < strlen(opt_arg); i++) {
1089 : switch (opt_arg[i]) {
1090 : case 'c':
1091 : opt_ssa_cp = true;
1092 : break;
1093 :
1094 : case 'd':
1095 : opt_ssa_dce = true;
1096 : break;
1097 :
1098 : case ':':
1099 : break;
1100 :
1101 : default:
1102 : usage();
1103 : }
1104 : }
1105 : break;
1106 : #endif
1107 :
1108 : case OPT_HELP:
1109 0 : usage();
1110 0 : break;
1111 :
1112 : case OPT_X:
1113 0 : Xusage();
1114 0 : break;
1115 :
1116 : case OPT_XX:
1117 : /* Already parsed. */
1118 22 : break;
1119 :
1120 : case OPT_EA:
1121 : #if defined(ENABLE_ASSERTION)
1122 10 : assertion_ea_da(opt_arg, true);
1123 : #endif
1124 10 : break;
1125 :
1126 : case OPT_DA:
1127 : #if defined(ENABLE_ASSERTION)
1128 10 : assertion_ea_da(opt_arg, false);
1129 : #endif
1130 10 : break;
1131 :
1132 : case OPT_EA_NOARG:
1133 : #if defined(ENABLE_ASSERTION)
1134 12 : assertion_user_enabled = true;
1135 : #endif
1136 12 : break;
1137 :
1138 : case OPT_DA_NOARG:
1139 : #if defined(ENABLE_ASSERTION)
1140 10 : assertion_user_enabled = false;
1141 : #endif
1142 10 : break;
1143 :
1144 : case OPT_ESA:
1145 : #if defined(ENABLE_ASSERTION)
1146 2 : assertion_system_enabled = true;
1147 : #endif
1148 2 : break;
1149 :
1150 : case OPT_DSA:
1151 : #if defined(ENABLE_ASSERTION)
1152 0 : assertion_system_enabled = false;
1153 : #endif
1154 0 : break;
1155 :
1156 : #if defined(ENABLE_PROFILING)
1157 : case OPT_PROF_OPTION:
1158 : /* use <= to get the last \0 too */
1159 :
1160 : for (unsigned int i = 0, j = 0; i <= strlen(opt_arg); i++) {
1161 : if (opt_arg[i] == ',')
1162 : opt_arg[i] = '\0';
1163 :
1164 : if (opt_arg[i] == '\0') {
1165 : if (strcmp("bb", opt_arg + j) == 0)
1166 : opt_prof_bb = true;
1167 :
1168 : else {
1169 : fprintf(stderr, "Unknown option: -Xprof:%s\n", opt_arg + j);
1170 : usage();
1171 : }
1172 :
1173 : /* set k to next char */
1174 :
1175 : j = i + 1;
1176 : }
1177 : }
1178 : /* fall through */
1179 :
1180 : case OPT_PROF:
1181 : opt_prof = true;
1182 : break;
1183 : #endif
1184 :
1185 : case OPT_JIT:
1186 : #if defined(ENABLE_JIT)
1187 0 : opt_jit = true;
1188 : #else
1189 : printf("-Xjit option not enabled.\n");
1190 : exit(1);
1191 : #endif
1192 0 : break;
1193 :
1194 : case OPT_INTRP:
1195 : #if defined(ENABLE_INTRP)
1196 : opt_intrp = true;
1197 : #else
1198 0 : printf("-Xint option not enabled.\n");
1199 0 : exit(1);
1200 : #endif
1201 : break;
1202 :
1203 : #if defined(ENABLE_INTRP)
1204 : case OPT_STATIC_SUPERS:
1205 : opt_static_supers = atoi(opt_arg);
1206 : break;
1207 :
1208 : case OPT_NO_DYNAMIC:
1209 : opt_no_dynamic = true;
1210 : break;
1211 :
1212 : case OPT_NO_REPLICATION:
1213 : opt_no_replication = true;
1214 : break;
1215 :
1216 : case OPT_NO_QUICKSUPER:
1217 : opt_no_quicksuper = true;
1218 : break;
1219 :
1220 : case OPT_TRACE:
1221 : vm_debug = true;
1222 : break;
1223 : #endif
1224 :
1225 : #if defined(ENABLE_DEBUG_FILTER)
1226 : case OPT_FILTER_VERBOSECALL_INCLUDE:
1227 0 : opt_filter_verbosecall_include = opt_arg;
1228 0 : break;
1229 :
1230 : case OPT_FILTER_VERBOSECALL_EXCLUDE:
1231 0 : opt_filter_verbosecall_exclude = opt_arg;
1232 0 : break;
1233 :
1234 : case OPT_FILTER_SHOW_METHOD:
1235 0 : opt_filter_show_method = opt_arg;
1236 0 : break;
1237 :
1238 : #endif
1239 : default:
1240 : fprintf(stderr, "Unknown option: %s\n",
1241 0 : vm_args->options[opt_index++].optionString);
1242 : }
1243 : }
1244 :
1245 : // Print the preliminary run-time VM configuration after options
1246 : // are parsed.
1247 163 : if (opt_PrintConfig)
1248 22 : print_run_time_config();
1249 :
1250 : /* initialize the garbage collector */
1251 :
1252 163 : gc_init(opt_heapmaxsize, opt_heapstartsize);
1253 :
1254 : /* AFTER: gc_init */
1255 :
1256 163 : threads_preinit();
1257 163 : lock_init();
1258 :
1259 : /* install architecture dependent signal handlers */
1260 :
1261 163 : if (!signal_init())
1262 0 : os::abort("vm_create: signal_init failed");
1263 :
1264 : #if defined(ENABLE_INTRP)
1265 : /* Allocate main thread stack on the Java heap. */
1266 :
1267 : if (opt_intrp) {
1268 : intrp_main_stack = GCMNEW(u1, opt_stacksize);
1269 : MSET(intrp_main_stack, 0, u1, opt_stacksize);
1270 : }
1271 : #endif
1272 :
1273 : /* AFTER: threads_preinit */
1274 :
1275 163 : JavaString::initialize();
1276 :
1277 : /* AFTER: threads_preinit */
1278 :
1279 163 : Utf8String::initialize();
1280 :
1281 : // Hook point before the VM is initialized.
1282 163 : Hook::vm_preinit();
1283 :
1284 : #if defined(ENABLE_JVMTI)
1285 : // AFTER: utf8_init
1286 : if (!_nativeagents.load_agents())
1287 : os::abort("vm_create: load_agents failed");
1288 : #endif
1289 :
1290 : /* AFTER: thread_preinit */
1291 :
1292 : /* Add -Xbootclasspath/p if it exists */
1293 163 : if (boot_class_path_p != NULL)
1294 0 : _suckclasspath.add(boot_class_path_p);
1295 :
1296 163 : _suckclasspath.add_from_property("java.endorsed.dirs");
1297 :
1298 : /* Now we have all options handled and we can print the version
1299 : information.
1300 :
1301 : AFTER: suck_add_from_property("java.endorsed.dirs"); */
1302 :
1303 163 : if (opt_version)
1304 0 : version(opt_exit);
1305 :
1306 : /* AFTER: utf8_init */
1307 :
1308 : // FIXME Make boot_class_path const char*.
1309 163 : boot_class_path = (char*) _properties.get("sun.boot.class.path");
1310 163 : _suckclasspath.add(boot_class_path);
1311 :
1312 : /* initialize the classcache hashtable stuff: lock, hashtable
1313 : (must be done _after_ threads_preinit) */
1314 :
1315 163 : if (!classcache_init())
1316 0 : os::abort("vm_create: classcache_init failed");
1317 :
1318 : /* Initialize the code memory management. */
1319 : /* AFTER: threads_preinit */
1320 :
1321 163 : codememory_init();
1322 :
1323 : /* initialize the finalizer stuff (must be done _after_
1324 : threads_preinit) */
1325 :
1326 163 : if (!finalizer_init())
1327 0 : os::abort("vm_create: finalizer_init failed");
1328 :
1329 : /* Initialize the JIT compiler. */
1330 :
1331 163 : jit_init();
1332 163 : code_init();
1333 163 : methodtree_init();
1334 :
1335 : /* AFTER: utf8_init, classcache_init */
1336 :
1337 163 : loader_preinit();
1338 163 : linker_preinit();
1339 :
1340 : // AFTER: loader_preinit, linker_preinit
1341 163 : Primitive::initialize_table();
1342 :
1343 163 : loader_init();
1344 163 : jobjects_register_dyn_offsets();
1345 163 : linker_init();
1346 :
1347 : // AFTER: loader_init, linker_init
1348 163 : Primitive::post_initialize_table();
1349 163 : method_init();
1350 :
1351 : #if defined(ENABLE_JIT)
1352 163 : trap_init();
1353 : #endif
1354 :
1355 163 : if (!builtin_init())
1356 0 : os::abort("vm_create: builtin_init failed");
1357 :
1358 : /* Register the native methods implemented in the VM. */
1359 : /* BEFORE: threads_init */
1360 :
1361 163 : nativevm_preinit();
1362 :
1363 : #if defined(ENABLE_JNI)
1364 : /* Initialize the JNI subsystem (must be done _before_
1365 : threads_init, as threads_init can call JNI methods
1366 : (e.g. NewGlobalRef). */
1367 :
1368 163 : if (!jni_init())
1369 0 : os::abort("vm_create: jni_init failed");
1370 : #endif
1371 :
1372 : #if defined(ENABLE_JNI) || defined(ENABLE_HANDLES)
1373 : /* Initialize the local reference table for the main thread. */
1374 : /* BEFORE: threads_init */
1375 :
1376 163 : if (!localref_table_init())
1377 0 : os::abort("vm_create: localref_table_init failed");
1378 : #endif
1379 :
1380 : /* Iinitialize some important system classes. */
1381 : /* BEFORE: threads_init */
1382 :
1383 163 : initialize_init();
1384 163 : threads_init();
1385 :
1386 : /* Initialize the native VM subsystem. */
1387 : /* AFTER: threads_init (at least for SUN's classes) */
1388 :
1389 163 : if (!nativevm_init())
1390 0 : os::abort("vm_create: nativevm_init failed");
1391 :
1392 : #if defined(ENABLE_PROFILING)
1393 : /* initialize profiling */
1394 :
1395 : if (!profile_init())
1396 : os::abort("vm_create: profile_init failed");
1397 : #endif
1398 :
1399 : /* start the signal handler thread */
1400 :
1401 : #if defined(__LINUX__)
1402 : /* XXX Remove for exact-GC. */
1403 163 : if (threads_pthreads_implementation_nptl)
1404 : #endif
1405 163 : if (!signal_start_thread())
1406 0 : os::abort("vm_create: signal_start_thread failed");
1407 :
1408 : /* finally, start the finalizer thread */
1409 :
1410 163 : if (!finalizer_start_thread())
1411 0 : os::abort("vm_create: finalizer_start_thread failed");
1412 :
1413 : #if !defined(NDEBUG)
1414 : /* start the memory profiling thread */
1415 :
1416 163 : if (opt_ProfileMemoryUsage || opt_ProfileGCMemoryUsage)
1417 0 : if (!memory_start_thread())
1418 0 : os::abort("vm_create: memory_start_thread failed");
1419 : #endif
1420 :
1421 : #ifdef ENABLE_THREADS
1422 : // Start the recompilation thread (must be done before the
1423 : // profiling thread).
1424 : // FIXME Only works for one recompiler.
1425 163 : _recompiler.start();
1426 : #endif
1427 :
1428 : #if defined(ENABLE_PROFILING)
1429 : /* start the profile sampling thread */
1430 :
1431 : /* if (opt_prof) */
1432 : /* if (!profile_start_thread()) */
1433 : /* os::abort("vm_create: profile_start_thread failed"); */
1434 : #endif
1435 :
1436 : /* Increment the number of VMs. */
1437 :
1438 163 : vms++;
1439 :
1440 : // Initialization is done, VM is created.
1441 163 : _created = true;
1442 163 : _initializing = false;
1443 :
1444 : // Set the VM inittime.
1445 163 : _inittime = builtin_currenttimemillis();
1446 :
1447 : // Hook point after the VM is initialized.
1448 163 : Hook::vm_init();
1449 :
1450 : // Print the run-time VM configuration after all stuff is set and
1451 : // the VM is initialized.
1452 163 : if (opt_PrintConfig)
1453 22 : print_run_time_config();
1454 :
1455 : // Start runtime agents after the VM is created.
1456 163 : if (!start_runtime_agents())
1457 0 : os::abort("vm_create: start_runtime_agents failed");
1458 0 : }
1459 :
1460 :
1461 : /**
1462 : * Print build-time (default) VM configuration.
1463 : */
1464 22 : void VM::print_build_time_config(void)
1465 : {
1466 22 : puts("CACAO " VERSION_FULL " configure/build options:");
1467 22 : puts("");
1468 22 : puts(" ./configure: " VERSION_CONFIGURE_ARGS "");
1469 : #if defined(__VERSION__)
1470 22 : puts(" CC : " VERSION_CC " (" __VERSION__ ")");
1471 22 : puts(" CXX : " VERSION_CXX " (" __VERSION__ ")");
1472 : #else
1473 : puts(" CC : " VERSION_CC "");
1474 : puts(" CXX : " VERSION_CXX "");
1475 : #endif
1476 22 : puts(" CFLAGS : " VERSION_CFLAGS "");
1477 22 : puts(" CXXFLAGS : " VERSION_CXXFLAGS "");
1478 22 : puts(" CPPFLAGS : " VERSION_CPPFLAGS "");
1479 :
1480 22 : puts("");
1481 :
1482 22 : puts("Build-time (default) variables:\n");
1483 22 : printf(" maximum heap size : %d\n", HEAP_MAXSIZE);
1484 22 : printf(" initial heap size : %d\n", HEAP_STARTSIZE);
1485 22 : printf(" stack size : %d\n", STACK_SIZE);
1486 :
1487 : #if defined(ENABLE_JRE_LAYOUT)
1488 : // When we're building with JRE-layout, the default paths are the
1489 : // same as the runtime paths.
1490 : #else
1491 : # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1492 22 : puts(" gnu.classpath.boot.library.path: " JAVA_RUNTIME_LIBRARY_LIBDIR);
1493 22 : puts(" java.boot.class.path : " CACAO_VM_ZIP ":" JAVA_RUNTIME_LIBRARY_CLASSES);
1494 : # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1495 : puts(" sun.boot.library.path : " JAVA_RUNTIME_LIBRARY_LIBDIR);
1496 : puts(" java.boot.class.path : " JAVA_RUNTIME_LIBRARY_CLASSES);
1497 : # endif
1498 : #endif
1499 :
1500 22 : puts("");
1501 22 : }
1502 :
1503 :
1504 : /**
1505 : * Print run-time VM configuration.
1506 : */
1507 44 : void VM::print_run_time_config()
1508 : {
1509 44 : puts("Run-time variables:\n");
1510 44 : printf(" maximum heap size : %d\n", opt_heapmaxsize);
1511 44 : printf(" initial heap size : %d\n", opt_heapstartsize);
1512 44 : printf(" stack size : %d\n", opt_stacksize);
1513 :
1514 : #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1515 44 : printf(" gnu.classpath.boot.library.path: %s\n", _properties.get("gnu.classpath.boot.library.path"));
1516 : #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1517 : printf(" sun.boot.library.path : %s\n", _properties.get("sun.boot.library.path"));
1518 : #endif
1519 :
1520 44 : printf(" java.boot.class.path : %s\n", _properties.get("java.boot.class.path"));
1521 44 : printf(" java.class.path : %s\n", _properties.get("java.class.path"));
1522 :
1523 44 : puts("");
1524 44 : }
1525 :
1526 :
1527 : /**
1528 : * Start runtime agents which are provided by the JRE but need to be
1529 : * started explicitly by the VM.
1530 : */
1531 163 : bool VM::start_runtime_agents()
1532 : {
1533 : #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1534 :
1535 : // Nothing to do.
1536 :
1537 : #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1538 :
1539 : // Check whether the management agent should be loaded.
1540 : if ((_properties.get("com.sun.management.jmxremote") != NULL) ||
1541 : (_properties.get("com.sun.management.snmp") != NULL))
1542 : {
1543 :
1544 : // Load the management agent class.
1545 : classinfo* class_sun_management_Agent;
1546 : if (!(class_sun_management_Agent = load_class_from_sysloader(Utf8String::from_utf8("sun/management/Agent"))))
1547 : return false;
1548 :
1549 : // Link the management agent class.
1550 : if (!link_class(class_sun_management_Agent))
1551 : return false;
1552 :
1553 : // Actually start the management agent.
1554 : methodinfo* m = class_resolveclassmethod(class_sun_management_Agent,
1555 : Utf8String::from_utf8("startAgent"),
1556 : utf8::void__void,
1557 : class_java_lang_Object,
1558 : false);
1559 :
1560 : if (m == NULL)
1561 : return false;
1562 :
1563 : (void) vm_call_method(m, NULL);
1564 :
1565 : if (exceptions_get_exception() != NULL)
1566 : return false;
1567 : }
1568 :
1569 : #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1570 :
1571 : // Nothing to do.
1572 :
1573 : #else
1574 : # error unknown classpath configuration
1575 : #endif
1576 :
1577 163 : return true;
1578 : }
1579 :
1580 : static void write_logfiles();
1581 :
1582 : /* vm_run **********************************************************************
1583 :
1584 : Runs the main-method of the passed class.
1585 :
1586 : *******************************************************************************/
1587 :
1588 163 : void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
1589 : {
1590 : methodinfo* m;
1591 : int status;
1592 :
1593 : #if !defined(NDEBUG)
1594 163 : if (opt_CompileAll) {
1595 0 : vm_compile_all();
1596 : /* write logfiles */
1597 0 : write_logfiles();
1598 0 : return;
1599 : }
1600 : #endif
1601 :
1602 : /* Get the main class or jar file argument. */
1603 :
1604 163 : char* mainname = NULL;
1605 :
1606 163 : if (opt_index < vm_args->nOptions) {
1607 : /* Get main-class argument. */
1608 :
1609 141 : mainname = vm_args->options[opt_index].optionString;
1610 :
1611 : /* If the main class argument is a jar file, put it into the
1612 : classpath. */
1613 :
1614 141 : if (opt_jar == true) {
1615 0 : char* p = MNEW(char, strlen(mainname) + strlen("0"));
1616 :
1617 0 : strcpy(p, mainname);
1618 :
1619 : #if defined(ENABLE_JAVASE)
1620 0 : VM::get_current()->get_properties().put("java.class.path", p);
1621 : #endif
1622 : }
1623 : else {
1624 : /* Replace dots with slashes in the class name. */
1625 :
1626 3955 : for (unsigned int i = 0; i < strlen(mainname); i++)
1627 3814 : if (mainname[i] == '.')
1628 20 : mainname[i] = '/';
1629 : }
1630 :
1631 : /* Move index to first argument. */
1632 :
1633 141 : opt_index++;
1634 : }
1635 :
1636 : /* Do we have a main-class argument? */
1637 :
1638 163 : if (mainname == NULL)
1639 22 : usage();
1640 :
1641 : #if defined(COMPILE_METHOD)
1642 141 : if (opt_CompileMethod != NULL) {
1643 0 : vm_compile_method(mainname);
1644 : /* write logfiles */
1645 0 : write_logfiles();
1646 0 : return;
1647 : }
1648 : #endif
1649 :
1650 : /* Build argument array. */
1651 :
1652 141 : int32_t oalength = vm_args->nOptions - opt_index;
1653 :
1654 141 : ObjectArray oa(oalength, class_java_lang_String);
1655 :
1656 141 : if (oa.is_null())
1657 0 : vm_exit(1);
1658 :
1659 235 : for (int i = 0; i < oalength; i++) {
1660 94 : char* option = vm_args->options[opt_index + i].optionString;
1661 :
1662 94 : java_handle_t* s = JavaString::from_utf8(option);
1663 :
1664 94 : oa.set_element(i, s);
1665 : }
1666 :
1667 : /* set return value to OK */
1668 :
1669 141 : status = 0;
1670 :
1671 141 : if (opt_jar == true) {
1672 : /* open jar file with java.util.jar.JarFile */
1673 :
1674 0 : mainname = vm_get_mainclass_from_jar(mainname);
1675 :
1676 0 : if (mainname == NULL)
1677 0 : vm_exit(1);
1678 : }
1679 :
1680 : /* load the main class */
1681 :
1682 141 : Utf8String mainutf = Utf8String::from_utf8(mainname);
1683 :
1684 : #if defined(ENABLE_JAVAME_CLDC1_1)
1685 : classinfo* mainclass = load_class_bootstrap(mainutf);
1686 : #else
1687 141 : classinfo* mainclass = load_class_from_sysloader(mainutf);
1688 : #endif
1689 :
1690 : /* error loading class */
1691 :
1692 141 : java_handle_t* e = exceptions_get_and_clear_exception();
1693 :
1694 141 : if ((e != NULL) || (mainclass == NULL)) {
1695 0 : exceptions_throw_noclassdeffounderror_cause(e);
1696 0 : exceptions_print_stacktrace();
1697 0 : vm_exit(1);
1698 : }
1699 :
1700 141 : if (!link_class(mainclass)) {
1701 0 : exceptions_print_stacktrace();
1702 0 : vm_exit(1);
1703 : }
1704 :
1705 : /* find the `main' method of the main class */
1706 :
1707 : m = class_resolveclassmethod(mainclass,
1708 : Utf8String::from_utf8("main"),
1709 : Utf8String::from_utf8("([Ljava/lang/String;)V"),
1710 : class_java_lang_Object,
1711 141 : false);
1712 :
1713 141 : if (exceptions_get_exception()) {
1714 0 : exceptions_print_stacktrace();
1715 0 : vm_exit(1);
1716 : }
1717 :
1718 : /* there is no main method or it isn't static */
1719 :
1720 141 : if ((m == NULL) || !(m->flags & ACC_STATIC)) {
1721 0 : exceptions_clear_exception();
1722 : exceptions_throw_nosuchmethoderror(mainclass,
1723 : Utf8String::from_utf8("main"),
1724 0 : Utf8String::from_utf8("([Ljava/lang/String;)V"));
1725 :
1726 0 : exceptions_print_stacktrace();
1727 0 : vm_exit(1);
1728 : }
1729 :
1730 : #ifdef TYPEINFO_DEBUG_TEST
1731 : /* test the typeinfo system */
1732 : typeinfo_test();
1733 : #endif
1734 :
1735 : /* start the main thread */
1736 :
1737 141 : (void) vm_call_method(m, NULL, oa.get_handle());
1738 :
1739 : /* exception occurred? */
1740 :
1741 131 : if (exceptions_get_exception()) {
1742 41 : exceptions_print_stacktrace();
1743 41 : status = 1;
1744 : }
1745 :
1746 : /* Detach the main thread so that it appears to have ended when
1747 : the application's main method exits. */
1748 :
1749 131 : if (!thread_detach_current_thread())
1750 0 : os::abort("vm_run: Could not detach main thread.");
1751 :
1752 : /* write logfiles */
1753 131 : write_logfiles();
1754 :
1755 : /* Destroy the JavaVM. */
1756 :
1757 131 : (void) vm_destroy(vm);
1758 :
1759 : /* And exit. */
1760 :
1761 131 : vm_exit(status);
1762 : }
1763 :
1764 :
1765 : /* vm_destroy ******************************************************************
1766 :
1767 : Unloads a Java VM and reclaims its resources.
1768 :
1769 : *******************************************************************************/
1770 :
1771 131 : int vm_destroy(JavaVM *vm)
1772 : {
1773 : /* Create a a trivial new Java waiter thread called
1774 : "DestroyJavaVM". */
1775 :
1776 : JavaVMAttachArgs args;
1777 :
1778 131 : args.name = (char*) "DestroyJavaVM";
1779 131 : args.group = NULL;
1780 :
1781 131 : if (!thread_attach_current_thread(&args, false))
1782 0 : return 1;
1783 :
1784 : /* Wait until we are the last non-daemon thread. */
1785 :
1786 131 : threads_join_all_threads();
1787 :
1788 : // Hook point before the VM is actually destroyed.
1789 131 : Hook::vm_shutdown();
1790 :
1791 : /* VM is gone. */
1792 :
1793 : // _created = false;
1794 :
1795 : /* Everything is ok. */
1796 :
1797 131 : return 0;
1798 : }
1799 :
1800 :
1801 : /* vm_exit *********************************************************************
1802 :
1803 : Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1804 :
1805 : *******************************************************************************/
1806 :
1807 131 : void vm_exit(s4 status)
1808 : {
1809 : methodinfo *m;
1810 :
1811 : /* signal that we are exiting */
1812 :
1813 : // _exiting = true;
1814 :
1815 131 : assert(class_java_lang_System);
1816 131 : assert(class_java_lang_System->state & CLASS_LOADED);
1817 :
1818 : #if defined(ENABLE_JVMTI)
1819 : if (jvmti || (dbgcom!=NULL)) {
1820 : jvmti_set_phase(JVMTI_PHASE_DEAD);
1821 : if (jvmti) jvmti_agentunload();
1822 : }
1823 : #endif
1824 :
1825 131 : if (!link_class(class_java_lang_System)) {
1826 0 : exceptions_print_stacktrace();
1827 0 : exit(1);
1828 : }
1829 :
1830 : /* call java.lang.System.exit(I)V */
1831 :
1832 : m = class_resolveclassmethod(class_java_lang_System,
1833 : Utf8String::from_utf8("exit"),
1834 : utf8::int__void,
1835 : class_java_lang_Object,
1836 131 : true);
1837 :
1838 131 : if (m == NULL) {
1839 0 : exceptions_print_stacktrace();
1840 0 : exit(1);
1841 : }
1842 :
1843 : /* call the exit function with passed exit status */
1844 :
1845 131 : (void) vm_call_method(m, NULL, status);
1846 :
1847 : /* If we had an exception, just ignore the exception and exit with
1848 : the proper code. */
1849 :
1850 0 : vm_shutdown(status);
1851 0 : }
1852 :
1853 :
1854 : /* vm_shutdown *****************************************************************
1855 :
1856 : Terminates the system immediately without freeing memory explicitly
1857 : (to be used only for abnormal termination).
1858 :
1859 : *******************************************************************************/
1860 :
1861 141 : void vm_shutdown(s4 status)
1862 : {
1863 141 : if (opt_verbose
1864 : #if defined(ENABLE_STATISTICS)
1865 : || opt_getcompilingtime || opt_stat
1866 : #endif
1867 : )
1868 : {
1869 0 : log_text("CACAO terminated by shutdown");
1870 0 : dolog("Exit status: %d\n", (s4) status);
1871 :
1872 : }
1873 :
1874 : #if defined(ENABLE_JVMTI)
1875 : /* terminate cacaodbgserver */
1876 : if (dbgcom!=NULL) {
1877 : mutex_lock(&dbgcomlock);
1878 : dbgcom->running=1;
1879 : mutex_unlock(&dbgcomlock);
1880 : jvmti_cacaodbgserver_quit();
1881 : }
1882 : #endif
1883 :
1884 : #if defined(ENABLE_THREADS)
1885 141 : finalizer_join_thread();
1886 : #endif
1887 :
1888 141 : exit(status);
1889 : }
1890 :
1891 : #include "toolbox/OStream.hpp"
1892 :
1893 : /* vm_exit_handler *************************************************************
1894 :
1895 : The exit_handler function is called upon program termination.
1896 :
1897 : ATTENTION: Don't free system resources here! Some threads may still
1898 : be running as this is called from VMRuntime.exit(). The OS does the
1899 : cleanup for us.
1900 :
1901 : *******************************************************************************/
1902 :
1903 165 : void vm_exit_handler(void)
1904 : {
1905 : #if !defined(NDEBUG)
1906 165 : if (showmethods)
1907 0 : class_showmethods(mainclass);
1908 :
1909 165 : if (showconstantpool)
1910 0 : class_showconstantpool(mainclass);
1911 :
1912 : # if defined(ENABLE_PROFILING)
1913 : if (opt_prof)
1914 : profile_printstats();
1915 : # endif
1916 : #endif /* !defined(NDEBUG) */
1917 :
1918 : #if defined(ENABLE_CYCLES_STATS)
1919 : builtin_print_cycles_stats(log_get_logfile());
1920 : stacktrace_print_cycles_stats(log_get_logfile());
1921 : #endif
1922 :
1923 165 : if (opt_verbose
1924 : #if defined(ENABLE_STATISTICS)
1925 : || opt_getcompilingtime || opt_stat
1926 : #endif
1927 : )
1928 : {
1929 0 : log_text("CACAO terminated");
1930 :
1931 : #if 0 && defined(ENABLE_STATISTICS)
1932 : if (opt_stat) {
1933 : #ifdef TYPECHECK_STATISTICS
1934 : // XXX TYPECHECK_STATISTICS is currently not usable
1935 : typecheck_print_statistics(get_logfile());
1936 : #endif
1937 : }
1938 :
1939 : #endif /* defined(ENABLE_STATISTICS) */
1940 : }
1941 : /* vm_print_profile(stderr);*/
1942 165 : }
1943 :
1944 131 : static void write_logfiles() {
1945 : #if defined(ENABLE_RT_TIMING)
1946 : if (!opt_RtTimingLogfile) {
1947 : FILE *file = fopen("rt-timing.log", "w");
1948 : if (file == NULL)
1949 : /* fallback to stdout */
1950 : file = stdout;
1951 : opt_RtTimingLogfile = file;
1952 : }
1953 : {
1954 : assert(opt_RtTimingLogfile);
1955 : cacao::OStream OS(opt_RtTimingLogfile);
1956 : if (!opt_RtTimingCSV) {
1957 : OS << "\nreal-time measurment:\n" << cacao::nl;
1958 : cacao::RTGroup::root().print(OS);
1959 : }
1960 : else {
1961 : cacao::RTGroup::print_csv_header(OS);
1962 : cacao::RTGroup::root().print_csv(OS);
1963 : }
1964 : }
1965 : #endif
1966 :
1967 : #if defined(ENABLE_STATISTICS)
1968 : if (!opt_StatisticsLogfile) {
1969 : FILE *file = fopen("statistics.log", "w");
1970 : if (file == NULL)
1971 : /* fallback to stdout */
1972 : file = stdout;
1973 : opt_StatisticsLogfile = file;
1974 : }
1975 : {
1976 : assert(opt_StatisticsLogfile);
1977 : cacao::OStream OS(opt_StatisticsLogfile);
1978 : if (!opt_StatisticsCSV) {
1979 : cacao::StatGroup::root().print(OS);
1980 : }
1981 : else {
1982 : cacao::StatGroup::print_csv_header(OS);
1983 : cacao::StatGroup::root().print_csv(OS);
1984 : }
1985 : }
1986 : #endif
1987 :
1988 131 : }
1989 :
1990 : /* vm_abort_disassemble ********************************************************
1991 :
1992 : Prints an error message, disassemble the given code range (if
1993 : enabled) and aborts the VM.
1994 :
1995 : IN:
1996 : pc.......PC to disassemble
1997 : count....number of instructions to disassemble
1998 :
1999 : *******************************************************************************/
2000 :
2001 0 : void vm_abort_disassemble(void *pc, int count, const char *text, ...)
2002 : {
2003 : va_list ap;
2004 : #if defined(ENABLE_DISASSEMBLER)
2005 : int i;
2006 : #endif
2007 :
2008 : /* Print debug message. */
2009 :
2010 0 : log_start();
2011 :
2012 0 : va_start(ap, text);
2013 0 : log_vprint(text, ap);
2014 0 : va_end(ap);
2015 :
2016 0 : log_finish();
2017 :
2018 : /* Print the PC. */
2019 :
2020 0 : log_println("PC=0x%0" PRINTF_INTPTR_NUM_HEXDIGITS PRIxPTR, (intptr_t) pc);
2021 :
2022 : #if defined(ENABLE_DISASSEMBLER)
2023 : log_println("machine instructions at PC:");
2024 :
2025 : /* Disassemble the given number of instructions. */
2026 :
2027 : for (i = 0; i < count; i++)
2028 : // FIXME disassinstr should use void*.
2029 : pc = disassinstr((u1*) pc);
2030 : #endif
2031 :
2032 0 : os::abort("Aborting...");
2033 0 : }
2034 :
2035 :
2036 : /* vm_get_mainclass_from_jar ***************************************************
2037 :
2038 : Gets the name of the main class from a JAR's manifest file.
2039 :
2040 : *******************************************************************************/
2041 :
2042 0 : static char *vm_get_mainclass_from_jar(char *mainname)
2043 : {
2044 : classinfo *c;
2045 : java_handle_t *o;
2046 : methodinfo *m;
2047 : java_handle_t *s;
2048 :
2049 : #if defined(ENABLE_JAVAME_CLDC1_1)
2050 : c = load_class_bootstrap(Utf8String::from_utf8("java/util/jar/JarFile"));
2051 : #else
2052 0 : c = load_class_from_sysloader(Utf8String::from_utf8("java/util/jar/JarFile"));
2053 : #endif
2054 :
2055 0 : if (c == NULL) {
2056 0 : exceptions_print_stacktrace();
2057 0 : return NULL;
2058 : }
2059 :
2060 : /* create JarFile object */
2061 :
2062 0 : o = builtin_new(c);
2063 :
2064 0 : if (o == NULL) {
2065 0 : exceptions_print_stacktrace();
2066 0 : return NULL;
2067 : }
2068 :
2069 : m = class_resolveclassmethod(c,
2070 : utf8::init,
2071 : utf8::java_lang_String__void,
2072 : class_java_lang_Object,
2073 0 : true);
2074 :
2075 0 : if (m == NULL) {
2076 0 : exceptions_print_stacktrace();
2077 0 : return NULL;
2078 : }
2079 :
2080 0 : s = JavaString::from_utf8(mainname);
2081 :
2082 0 : (void) vm_call_method(m, o, s);
2083 :
2084 0 : if (exceptions_get_exception()) {
2085 0 : exceptions_print_stacktrace();
2086 0 : return NULL;
2087 : }
2088 :
2089 : /* get manifest object */
2090 :
2091 : m = class_resolveclassmethod(c,
2092 : Utf8String::from_utf8("getManifest"),
2093 : Utf8String::from_utf8("()Ljava/util/jar/Manifest;"),
2094 : class_java_lang_Object,
2095 0 : true);
2096 :
2097 0 : if (m == NULL) {
2098 0 : exceptions_print_stacktrace();
2099 0 : return NULL;
2100 : }
2101 :
2102 0 : o = vm_call_method(m, o);
2103 :
2104 0 : if (o == NULL) {
2105 0 : fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainname);
2106 0 : return NULL;
2107 : }
2108 :
2109 :
2110 : /* get Main Attributes */
2111 :
2112 0 : LLNI_class_get(o, c);
2113 :
2114 : m = class_resolveclassmethod(c,
2115 : Utf8String::from_utf8("getMainAttributes"),
2116 : Utf8String::from_utf8("()Ljava/util/jar/Attributes;"),
2117 : class_java_lang_Object,
2118 0 : true);
2119 :
2120 0 : if (m == NULL) {
2121 0 : exceptions_print_stacktrace();
2122 0 : return NULL;
2123 : }
2124 :
2125 0 : o = vm_call_method(m, o);
2126 :
2127 0 : if (o == NULL) {
2128 0 : fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainname);
2129 0 : return NULL;
2130 : }
2131 :
2132 :
2133 : /* get property Main-Class */
2134 :
2135 0 : LLNI_class_get(o, c);
2136 :
2137 : m = class_resolveclassmethod(c,
2138 : Utf8String::from_utf8("getValue"),
2139 : Utf8String::from_utf8("(Ljava/lang/String;)Ljava/lang/String;"),
2140 : class_java_lang_Object,
2141 0 : true);
2142 :
2143 0 : if (m == NULL) {
2144 0 : exceptions_print_stacktrace();
2145 0 : return NULL;
2146 : }
2147 :
2148 0 : s = JavaString::from_utf8("Main-Class");
2149 :
2150 0 : o = vm_call_method(m, o, s);
2151 :
2152 0 : if (o == NULL) {
2153 0 : fprintf(stderr, "Failed to load Main-Class manifest attribute from\n");
2154 0 : fprintf(stderr, "%s\n", mainname);
2155 0 : return NULL;
2156 : }
2157 :
2158 0 : return JavaString(o).to_chars();
2159 : }
2160 :
2161 :
2162 : /* vm_compile_all **************************************************************
2163 :
2164 : Compile all methods found in the bootclasspath.
2165 :
2166 : *******************************************************************************/
2167 :
2168 : #if !defined(NDEBUG)
2169 0 : static void vm_compile_all(void)
2170 : {
2171 : classinfo *c;
2172 : methodinfo *m;
2173 : u4 slot;
2174 : classcache_name_entry *nmen;
2175 : classcache_class_entry *clsen;
2176 : s4 i;
2177 :
2178 : /* create all classes found in the bootclasspath */
2179 : /* XXX currently only works with zip/jar's */
2180 :
2181 0 : loader_load_all_classes();
2182 :
2183 : /* link all classes */
2184 :
2185 0 : for (slot = 0; slot < hashtable_classcache.size; slot++) {
2186 0 : nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
2187 :
2188 0 : for (; nmen; nmen = nmen->hashlink) {
2189 : /* iterate over all class entries */
2190 :
2191 0 : for (clsen = nmen->classes; clsen; clsen = clsen->next) {
2192 0 : c = clsen->classobj;
2193 :
2194 0 : if (c == NULL)
2195 0 : continue;
2196 :
2197 0 : if (!(c->state & CLASS_LINKED)) {
2198 0 : if (!link_class(c)) {
2199 0 : fprintf(stderr, "Error linking: ");
2200 0 : utf_fprint_printable_ascii_classname(stderr, c->name);
2201 0 : fprintf(stderr, "\n");
2202 :
2203 : /* print out exception and cause */
2204 :
2205 0 : exceptions_print_current_exception();
2206 :
2207 : /* goto next class */
2208 :
2209 0 : continue;
2210 : }
2211 : }
2212 :
2213 : /* compile all class methods */
2214 :
2215 0 : for (i = 0; i < c->methodscount; i++) {
2216 0 : m = &(c->methods[i]);
2217 :
2218 0 : if (m->jcode != NULL) {
2219 0 : if (!jit_compile(m)) {
2220 0 : fprintf(stderr, "Error compiling: ");
2221 0 : utf_fprint_printable_ascii_classname(stderr, c->name);
2222 0 : fprintf(stderr, ".");
2223 0 : utf_fprint_printable_ascii(stderr, m->name);
2224 0 : utf_fprint_printable_ascii(stderr, m->descriptor);
2225 0 : fprintf(stderr, "\n");
2226 :
2227 : /* print out exception and cause */
2228 :
2229 0 : exceptions_print_current_exception();
2230 : }
2231 : }
2232 : }
2233 : }
2234 : }
2235 : }
2236 0 : }
2237 : #endif /* !defined(NDEBUG) */
2238 :
2239 :
2240 : /* vm_compile_method ***********************************************************
2241 :
2242 : Compile a specific method.
2243 :
2244 : *******************************************************************************/
2245 :
2246 : RT_REGISTER_TIMER(compiler_method,"compiler-all","compiler overall")
2247 :
2248 : #if defined(COMPILE_METHOD)
2249 :
2250 : #if defined(ENABLE_COMPILER2)
2251 : #include "vm/jit/compiler2/Compiler.hpp"
2252 : #endif
2253 :
2254 0 : static void vm_compile_method(char* mainname)
2255 : {
2256 : methodinfo *m;
2257 :
2258 0 : if (opt_jar == true) {
2259 : /* open jar file with java.util.jar.JarFile */
2260 :
2261 0 : mainname = vm_get_mainclass_from_jar(mainname);
2262 :
2263 0 : if (mainname == NULL)
2264 0 : vm_exit(1);
2265 : }
2266 :
2267 : /* load the main class */
2268 :
2269 0 : Utf8String mainutf = Utf8String::from_utf8(mainname);
2270 :
2271 0 : classinfo* mainclass = load_class_bootstrap(mainutf);
2272 :
2273 : /* error loading class */
2274 :
2275 0 : java_handle_t* e = exceptions_get_and_clear_exception();
2276 :
2277 0 : if ((e != NULL) || (mainclass == NULL)) {
2278 0 : exceptions_throw_noclassdeffounderror_cause(e);
2279 0 : exceptions_print_stacktrace();
2280 0 : vm_exit(1);
2281 : }
2282 :
2283 0 : if (!link_class(mainclass)) {
2284 0 : exceptions_print_stacktrace();
2285 0 : vm_exit(1);
2286 : }
2287 :
2288 0 : if (opt_CompileSignature != NULL) {
2289 : m = class_resolveclassmethod(mainclass,
2290 : Utf8String::from_utf8(opt_CompileMethod),
2291 : Utf8String::from_utf8(opt_CompileSignature),
2292 : mainclass,
2293 0 : false);
2294 : }
2295 : else {
2296 : m = class_resolveclassmethod(mainclass,
2297 : Utf8String::from_utf8(opt_CompileMethod),
2298 : NULL,
2299 : mainclass,
2300 0 : false);
2301 : }
2302 :
2303 0 : if (m == NULL)
2304 : os::abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
2305 0 : opt_CompileMethod, opt_CompileSignature ? opt_CompileSignature : "");
2306 :
2307 : RT_TIMER_START(compiler_method);
2308 : #if defined(ENABLE_COMPILER2)
2309 0 : if (cacao::jit::compiler2::enabled) {
2310 0 : cacao::jit::compiler2::compile(m);
2311 : } else
2312 : #endif
2313 : {
2314 0 : jit_compile(m);
2315 : }
2316 : RT_TIMER_STOP(compiler_method);
2317 0 : }
2318 : #endif /* !defined(NDEBUG) */
2319 :
2320 :
2321 : /* vm_call_array ***************************************************************
2322 :
2323 : Calls a Java method with a variable number of arguments, passed via
2324 : an argument array.
2325 :
2326 : ATTENTION: This function has to be used outside the nativeworld.
2327 :
2328 : *******************************************************************************/
2329 :
2330 : #define VM_CALL_ARRAY(name, type) \
2331 : static type vm_call##name##_array(methodinfo *m, uint64_t *array) \
2332 : { \
2333 : methoddesc *md; \
2334 : void *pv; \
2335 : type value; \
2336 : \
2337 : assert(m->code != NULL); \
2338 : \
2339 : md = m->parseddesc; \
2340 : pv = m->code->entrypoint; \
2341 : \
2342 : STATISTICS(count_calls_native_to_java++); \
2343 : \
2344 : value = asm_vm_call_method##name(pv, array, md->memuse); \
2345 : \
2346 : return value; \
2347 : }
2348 :
2349 365295 : static java_handle_t *vm_call_array(methodinfo *m, uint64_t *array)
2350 : {
2351 : methoddesc *md;
2352 : void *pv;
2353 : java_object_t *o;
2354 :
2355 365295 : assert(m->code != NULL);
2356 :
2357 365295 : md = m->parseddesc;
2358 365295 : pv = m->code->entrypoint;
2359 :
2360 : STATISTICS(count_calls_native_to_java++);
2361 :
2362 365295 : o = asm_vm_call_method(pv, array, md->memuse);
2363 :
2364 365132 : if (md->returntype.type == TYPE_VOID)
2365 71919 : o = NULL;
2366 :
2367 365132 : return LLNI_WRAP(o);
2368 : }
2369 :
2370 381295 : VM_CALL_ARRAY(_int, int32_t)
2371 6 : VM_CALL_ARRAY(_long, int64_t)
2372 7 : VM_CALL_ARRAY(_float, float)
2373 7 : VM_CALL_ARRAY(_double, double)
2374 :
2375 :
2376 : /* vm_call_method **************************************************************
2377 :
2378 : Calls a Java method with a variable number of arguments.
2379 :
2380 : *******************************************************************************/
2381 :
2382 : #define VM_CALL_METHOD(name, type) \
2383 : type vm_call_##name(methodinfo *m, java_handle_t *o, ...) \
2384 : { \
2385 : va_list ap; \
2386 : type value; \
2387 : \
2388 : va_start(ap, o); \
2389 : value = vm_call_##name##_valist(m, o, ap); \
2390 : va_end(ap); \
2391 : \
2392 : return value; \
2393 : }
2394 :
2395 79877 : VM_CALL_METHOD(method, java_handle_t *)
2396 12 : VM_CALL_METHOD(method_int, int32_t)
2397 0 : VM_CALL_METHOD(method_long, int64_t)
2398 0 : VM_CALL_METHOD(method_float, float)
2399 0 : VM_CALL_METHOD(method_double, double)
2400 :
2401 :
2402 : /* vm_call_method_valist *******************************************************
2403 :
2404 : Calls a Java method with a variable number of arguments, passed via
2405 : a va_list.
2406 :
2407 : *******************************************************************************/
2408 :
2409 : #define VM_CALL_METHOD_VALIST(name, type) \
2410 : type vm_call_method##name##valist(methodinfo *m, java_handle_t *o, \
2411 : va_list ap) \
2412 : { \
2413 : uint64_t *array; \
2414 : type value; \
2415 : \
2416 : if (m->code == NULL) \
2417 : if (!jit_compile(m)) \
2418 : return 0; \
2419 : \
2420 : THREAD_NATIVEWORLD_EXIT; \
2421 : \
2422 : DumpMemoryArea dma; \
2423 : \
2424 : array = argument_vmarray_from_valist(m, o, ap); \
2425 : value = vm_call##name##array(m, array); \
2426 : \
2427 : THREAD_NATIVEWORLD_ENTER; \
2428 : \
2429 : return value; \
2430 : }
2431 :
2432 364507 : VM_CALL_METHOD_VALIST(_, java_handle_t *)
2433 381237 : VM_CALL_METHOD_VALIST(_int_, int32_t)
2434 0 : VM_CALL_METHOD_VALIST(_long_, int64_t)
2435 0 : VM_CALL_METHOD_VALIST(_float_, float)
2436 0 : VM_CALL_METHOD_VALIST(_double_, double)
2437 :
2438 :
2439 : /* vm_call_method_jvalue *******************************************************
2440 :
2441 : Calls a Java method with a variable number of arguments, passed via
2442 : a jvalue array.
2443 :
2444 : *******************************************************************************/
2445 :
2446 : #define VM_CALL_METHOD_JVALUE(name, type) \
2447 : type vm_call_method##name##jvalue(methodinfo *m, java_handle_t *o, \
2448 : const jvalue *args) \
2449 : { \
2450 : uint64_t *array; \
2451 : type value; \
2452 : \
2453 : if (m->code == NULL) \
2454 : if (!jit_compile(m)) \
2455 : return 0; \
2456 : \
2457 : THREAD_NATIVEWORLD_EXIT; \
2458 : \
2459 : DumpMemoryArea dma; \
2460 : \
2461 : array = argument_vmarray_from_jvalue(m, o, args); \
2462 : value = vm_call##name##array(m, array); \
2463 : \
2464 : THREAD_NATIVEWORLD_ENTER; \
2465 : \
2466 : return value; \
2467 : }
2468 :
2469 0 : VM_CALL_METHOD_JVALUE(_, java_handle_t *)
2470 0 : VM_CALL_METHOD_JVALUE(_int_, int32_t)
2471 0 : VM_CALL_METHOD_JVALUE(_long_, int64_t)
2472 0 : VM_CALL_METHOD_JVALUE(_float_, float)
2473 0 : VM_CALL_METHOD_JVALUE(_double_, double)
2474 :
2475 :
2476 : /* vm_call_method_objectarray **************************************************
2477 :
2478 : Calls a Java method with a variable number if arguments, passed via
2479 : an objectarray of boxed values. Returns a boxed value.
2480 :
2481 : *******************************************************************************/
2482 :
2483 853 : java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o,
2484 : java_handle_objectarray_t *params)
2485 : {
2486 : uint64_t *array;
2487 : java_handle_t *xptr;
2488 : java_handle_t *ro;
2489 : imm_union value;
2490 :
2491 : /* Prevent compiler warnings. */
2492 :
2493 853 : ro = NULL;
2494 :
2495 : /* compile methods which are not yet compiled */
2496 :
2497 853 : if (m->code == NULL)
2498 281 : if (!jit_compile(m))
2499 0 : return NULL;
2500 :
2501 : /* leave the nativeworld */
2502 :
2503 : THREAD_NATIVEWORLD_EXIT;
2504 :
2505 : // Create new dump memory area.
2506 853 : DumpMemoryArea dma;
2507 :
2508 : /* Fill the argument array from a object-array. */
2509 :
2510 853 : array = argument_vmarray_from_objectarray(m, o, params);
2511 :
2512 853 : if (array == NULL) {
2513 : /* enter the nativeworld again */
2514 :
2515 : THREAD_NATIVEWORLD_ENTER;
2516 :
2517 0 : exceptions_throw_illegalargumentexception();
2518 :
2519 0 : return NULL;
2520 : }
2521 :
2522 853 : switch (m->parseddesc->returntype.primitivetype) {
2523 : case PRIMITIVETYPE_VOID:
2524 499 : value.a = vm_call_array(m, array);
2525 499 : break;
2526 :
2527 : case PRIMITIVETYPE_BOOLEAN:
2528 : case PRIMITIVETYPE_BYTE:
2529 : case PRIMITIVETYPE_CHAR:
2530 : case PRIMITIVETYPE_SHORT:
2531 : case PRIMITIVETYPE_INT:
2532 58 : value.i = vm_call_int_array(m, array);
2533 58 : break;
2534 :
2535 : case PRIMITIVETYPE_LONG:
2536 6 : value.l = vm_call_long_array(m, array);
2537 6 : break;
2538 :
2539 : case PRIMITIVETYPE_FLOAT:
2540 7 : value.f = vm_call_float_array(m, array);
2541 7 : break;
2542 :
2543 : case PRIMITIVETYPE_DOUBLE:
2544 7 : value.d = vm_call_double_array(m, array);
2545 7 : break;
2546 :
2547 : case TYPE_ADR:
2548 276 : ro = vm_call_array(m, array);
2549 276 : break;
2550 :
2551 : default:
2552 0 : os::abort("vm_call_method_objectarray: invalid return type %d", m->parseddesc->returntype.primitivetype);
2553 : }
2554 :
2555 : /* enter the nativeworld again */
2556 :
2557 : THREAD_NATIVEWORLD_ENTER;
2558 :
2559 : /* box the return value if necesarry */
2560 :
2561 853 : if (m->parseddesc->returntype.primitivetype != (PrimitiveType) TYPE_ADR)
2562 577 : ro = Primitive::box(m->parseddesc->returntype.primitivetype, value);
2563 :
2564 : /* check for an exception */
2565 :
2566 853 : xptr = exceptions_get_exception();
2567 :
2568 853 : if (xptr != NULL) {
2569 : /* clear exception pointer, we are calling JIT code again */
2570 :
2571 11 : exceptions_clear_exception();
2572 :
2573 11 : exceptions_throw_invocationtargetexception(xptr);
2574 : }
2575 :
2576 853 : return ro;
2577 : }
2578 :
2579 :
2580 : /* Legacy C interface *********************************************************/
2581 :
2582 : extern "C" {
2583 :
2584 0 : JNIEnv* VM_get_jnienv() { return VM::get_current()->get_jnienv(); }
2585 :
2586 0 : void vm_abort(const char* text, ...)
2587 : {
2588 : va_list ap;
2589 :
2590 0 : log_println("vm_abort: WARNING, port me to C++ and use os::abort() instead.");
2591 :
2592 : // Print the log message.
2593 0 : log_start();
2594 :
2595 0 : va_start(ap, text);
2596 0 : log_vprint(text, ap);
2597 0 : va_end(ap);
2598 :
2599 0 : log_finish();
2600 :
2601 : // Print a backtrace.
2602 0 : os::print_backtrace();
2603 :
2604 : // Now abort the VM.
2605 0 : os::abort();
2606 0 : }
2607 :
2608 : }
2609 :
2610 :
2611 : /*
2612 : * These are local overrides for various environment variables in Emacs.
2613 : * Please do not remove this and leave it at the end of the file, where
2614 : * Emacs will automagically detect them.
2615 : * ---------------------------------------------------------------------
2616 : * Local variables:
2617 : * mode: c++
2618 : * indent-tabs-mode: t
2619 : * c-basic-offset: 4
2620 : * tab-width: 4
2621 : * End:
2622 : * vim:noexpandtab:sw=4:ts=4:
2623 : */
|