1 /* src/vm/vm.c - VM startup and shutdown functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: vm.c 8239 2007-07-29 19:21:18Z twisti $
37 #if defined(WITH_JRE_LAYOUT)
47 #include "vm/jit/abi-asm.h"
49 #include "mm/gc-common.h"
50 #include "mm/memory.h"
52 #include "native/jni.h"
53 #include "native/native.h"
55 #include "native/include/java_lang_Object.h" /* required by j.l.C */
56 #include "native/include/java_lang_String.h" /* required by j.l.C */
58 #if defined(WITH_CLASSPATH_SUN)
59 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
60 # include "native/include/java_lang_ClassLoader.h" /* required by j.l.C */
63 #include "native/include/java_lang_Class.h"
65 #include "native/include/java_lang_Byte.h"
66 #include "native/include/java_lang_Character.h"
67 #include "native/include/java_lang_Short.h"
68 #include "native/include/java_lang_Integer.h"
69 #include "native/include/java_lang_Boolean.h"
70 #include "native/include/java_lang_Long.h"
71 #include "native/include/java_lang_Float.h"
72 #include "native/include/java_lang_Double.h"
74 #include "native/vm/nativevm.h"
76 #include "threads/threads-common.h"
78 #include "toolbox/logging.h"
80 #include "vm/builtin.h"
81 #include "vm/exceptions.h"
82 #include "vm/finalizer.h"
83 #include "vm/global.h"
84 #include "vm/initialize.h"
85 #include "vm/properties.h"
86 #include "vm/signallocal.h"
87 #include "vm/stringlocal.h"
90 #include "vm/jit/jit.h"
91 #include "vm/jit/md.h"
92 #include "vm/jit/asmpart.h"
94 #if defined(ENABLE_PROFILING)
95 # include "vm/jit/optimizing/profile.h"
98 #include "vm/jit/optimizing/recompile.h"
100 #include "vmcore/classcache.h"
101 #include "vmcore/options.h"
102 #include "vmcore/primitive.h"
103 #include "vmcore/statistics.h"
104 #include "vmcore/suck.h"
106 #if defined(ENABLE_JVMTI)
107 # include "native/jvmti/cacaodbg.h"
110 #if defined(ENABLE_VMLOG)
111 #include <vmlog_cacao.h>
115 /* Invocation API variables ***************************************************/
117 _Jv_JavaVM *_Jv_jvm; /* denotes a Java VM */
118 _Jv_JNIEnv *_Jv_env; /* pointer to native method interface */
121 /* global variables ***********************************************************/
123 s4 vms = 0; /* number of VMs created */
125 bool vm_initializing = false;
126 bool vm_exiting = false;
128 char *cacao_prefix = NULL;
129 char *cacao_libjvm = NULL;
130 char *classpath_libdir = NULL;
132 char *_Jv_bootclasspath; /* contains the boot classpath */
133 char *_Jv_classpath; /* contains the classpath */
134 char *_Jv_java_library_path;
136 char *mainstring = NULL;
137 classinfo *mainclass = NULL;
139 char *specificmethodname = NULL;
140 char *specificsignature = NULL;
144 #if defined(ENABLE_INTRP)
145 u1 *intrp_main_stack = NULL;
149 /* define heap sizes **********************************************************/
151 #define HEAP_MAXSIZE 128 * 1024 * 1024 /* default 128MB */
152 #define HEAP_STARTSIZE 2 * 1024 * 1024 /* default 2MB */
153 #define STACK_SIZE 64 * 1024 /* default 64kB */
156 /* define command line options ************************************************/
187 /* Java non-standard options */
198 #if defined(ENABLE_PROFILING)
211 #if defined(ENABLE_STATISTICS)
228 #if defined(ENABLE_VERIFIER)
230 #if defined(TYPECHECK_VERBOSE)
233 #endif /* defined(ENABLE_VERIFIER) */
235 /* optimization options */
237 #if defined(ENABLE_LOOP)
241 #if defined(ENABLE_IFCONV)
245 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
249 #if defined(ENABLE_INLINING)
254 #if defined(ENABLE_INLINING_DEBUG)
255 OPT_INLINE_DEBUG_ALL,
256 OPT_INLINE_DEBUG_END,
257 OPT_INLINE_DEBUG_MIN,
258 OPT_INLINE_DEBUG_MAX,
259 #endif /* defined(ENABLE_INLINING_DEBUG) */
260 #endif /* defined(ENABLE_INLINING) */
262 #if defined(ENABLE_INTRP)
263 /* interpreter options */
282 #if defined(ENABLE_DEBUG_FILTER)
283 OPT_FILTER_VERBOSECALL_INCLUDE,
284 OPT_FILTER_VERBOSECALL_EXCLUDE,
285 OPT_FILTER_SHOW_METHOD,
292 opt_struct opts[] = {
293 { "foo", false, OPT_FOO },
297 { "jar", false, OPT_JAR },
299 { "d32", false, OPT_D32 },
300 { "d64", false, OPT_D64 },
301 { "client", false, OPT_IGNORE },
302 { "server", false, OPT_IGNORE },
303 { "jvm", false, OPT_IGNORE },
304 { "hotspot", false, OPT_IGNORE },
306 { "classpath", true, OPT_CLASSPATH },
307 { "cp", true, OPT_CLASSPATH },
308 { "D", true, OPT_D },
309 { "version", false, OPT_VERSION },
310 { "showversion", false, OPT_SHOWVERSION },
311 { "fullversion", false, OPT_FULLVERSION },
312 { "help", false, OPT_HELP },
313 { "?", false, OPT_HELP },
314 { "X", false, OPT_X },
315 { "XX:", true, OPT_XX },
316 { "XX", false, OPT_XX },
318 { "ea:", true, OPT_EA },
319 { "da:", true, OPT_DA },
320 { "ea", false, OPT_EA },
321 { "da", false, OPT_DA },
323 { "esa", false, OPT_ESA },
324 { "enablesystemassertions", false, OPT_ESA },
325 { "dsa", false, OPT_DSA },
326 { "disablesystemassertions", false, OPT_DSA },
328 { "noasyncgc", false, OPT_IGNORE },
329 #if defined(ENABLE_VERIFIER)
330 { "noverify", false, OPT_NOVERIFY },
332 { "v", false, OPT_VERBOSE1 },
333 { "verbose:", true, OPT_VERBOSE },
335 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
336 { "verbosetc", false, OPT_VERBOSETC },
338 #if defined(__ALPHA__)
339 { "noieee", false, OPT_NOIEEE },
341 #if defined(ENABLE_STATISTICS)
342 { "time", false, OPT_TIME },
343 { "stat", false, OPT_STAT },
345 { "log", true, OPT_LOG },
346 { "c", true, OPT_CHECK },
347 { "l", false, OPT_LOAD },
350 { "all", false, OPT_ALL },
351 { "sig", true, OPT_SIGNATURE },
354 #if defined(ENABLE_LOOP)
355 { "oloop", false, OPT_OLOOP },
357 #if defined(ENABLE_IFCONV)
358 { "ifconv", false, OPT_IFCONV },
360 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
361 { "lsra", false, OPT_LSRA },
364 #if defined(ENABLE_INTRP)
365 /* interpreter options */
367 { "trace", false, OPT_TRACE },
368 { "static-supers", true, OPT_STATIC_SUPERS },
369 { "no-dynamic", false, OPT_NO_DYNAMIC },
370 { "no-replication", false, OPT_NO_REPLICATION },
371 { "no-quicksuper", false, OPT_NO_QUICKSUPER },
374 /* JVMTI Agent Command Line Options */
376 { "agentlib:", true, OPT_AGENTLIB },
377 { "agentpath:", true, OPT_AGENTPATH },
380 /* Java non-standard options */
382 { "Xjit", false, OPT_JIT },
383 { "Xint", false, OPT_INTRP },
384 { "Xbootclasspath:", true, OPT_BOOTCLASSPATH },
385 { "Xbootclasspath/a:", true, OPT_BOOTCLASSPATH_A },
386 { "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P },
387 { "Xbootclasspath/c:", true, OPT_BOOTCLASSPATH_C },
390 { "Xdebug", false, OPT_DEBUG },
391 { "Xnoagent", false, OPT_NOAGENT },
392 { "Xrunjdwp", true, OPT_XRUNJDWP },
395 { "Xms", true, OPT_MS },
396 { "ms", true, OPT_MS },
397 { "Xmx", true, OPT_MX },
398 { "mx", true, OPT_MX },
399 { "Xss", true, OPT_SS },
400 { "ss", true, OPT_SS },
402 #if defined(ENABLE_PROFILING)
403 { "Xprof:", true, OPT_PROF_OPTION },
404 { "Xprof", false, OPT_PROF },
407 /* inlining options */
409 #if defined(ENABLE_INLINING)
410 #if defined(ENABLE_INLINING_DEBUG)
411 { "ia", false, OPT_INLINE_DEBUG_ALL },
412 { "ii", true, OPT_INLINE_DEBUG_MIN },
413 { "im", true, OPT_INLINE_DEBUG_MAX },
414 { "ie", true, OPT_INLINE_DEBUG_END },
415 #endif /* defined(ENABLE_INLINING_DEBUG) */
417 { "il", false, OPT_INLINE_LOG },
419 { "i", false, OPT_INLINING },
420 #endif /* defined(ENABLE_INLINING) */
422 /* keep these at the end of the list */
425 { "m", true, OPT_METHOD },
428 { "s", true, OPT_SHOW },
429 { "debug-color", false, OPT_DEBUGCOLOR },
431 #if defined(ENABLE_DEBUG_FILTER)
432 { "XXfi", true, OPT_FILTER_VERBOSECALL_INCLUDE },
433 { "XXfx", true, OPT_FILTER_VERBOSECALL_EXCLUDE },
434 { "XXfm", true, OPT_FILTER_SHOW_METHOD },
441 /* usage ***********************************************************************
443 Prints the correct usage syntax to stdout.
445 *******************************************************************************/
449 puts("Usage: cacao [-options] classname [arguments]");
450 puts(" (to run a class file)");
451 puts(" or cacao [-options] -jar jarfile [arguments]");
452 puts(" (to run a standalone jar file)\n");
454 puts("where options include:");
455 puts(" -d32 use 32-bit data model if available");
456 puts(" -d64 use 64-bit data model if available");
457 puts(" -client compatibility (currently ignored)");
458 puts(" -server compatibility (currently ignored)");
459 puts(" -jvm compatibility (currently ignored)");
460 puts(" -hotspot compatibility (currently ignored)\n");
462 puts(" -cp <path> specify a path to look for classes");
463 puts(" -classpath <path> specify a path to look for classes");
464 puts(" -D<name>=<value> add an entry to the property list");
465 puts(" -verbose[:class|gc|jni] enable specific verbose output");
466 puts(" -version print product version and exit");
467 puts(" -fullversion print jpackage-compatible product version and exit");
468 puts(" -showversion print product version and continue");
469 puts(" -help, -? print this help message");
470 puts(" -X print help on non-standard Java options");
471 puts(" -XX print help on debugging options");
472 puts(" -ea[:<packagename>...|:<classname>]");
473 puts(" -enableassertions[:<packagename>...|:<classname>]");
474 puts(" enable assertions with specified granularity");
475 puts(" -da[:<packagename>...|:<classname>]");
476 puts(" -disableassertions[:<packagename>...|:<classname>]");
477 puts(" disable assertions with specified granularity");
478 puts(" -esa | -enablesystemassertions");
479 puts(" enable system assertions");
480 puts(" -dsa | -disablesystemassertions");
481 puts(" disable system assertions");
484 puts(" -agentlib:<agent-lib-name>=<options> library to load containg JVMTI agent");
485 puts (" for jdwp help use: -agentlib:jdwp=help");
486 puts(" -agentpath:<path-to-agent>=<options> path to library containg JVMTI agent");
489 /* exit with error code */
495 static void Xusage(void)
497 #if defined(ENABLE_JIT)
498 puts(" -Xjit JIT mode execution (default)");
500 #if defined(ENABLE_INTRP)
501 puts(" -Xint interpreter mode execution");
503 puts(" -Xbootclasspath:<zip/jar files and directories separated by :>");
504 puts(" value is set as bootstrap class path");
505 puts(" -Xbootclasspath/a:<zip/jar files and directories separated by :>");
506 puts(" value is appended to the bootstrap class path");
507 puts(" -Xbootclasspath/p:<zip/jar files and directories separated by :>");
508 puts(" value is prepended to the bootstrap class path");
509 puts(" -Xbootclasspath/c:<zip/jar files and directories separated by :>");
510 puts(" value is used as Java core library, but the");
511 puts(" hardcoded VM interface classes are prepended");
512 printf(" -Xms<size> set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
513 printf(" -Xmx<size> set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
514 printf(" -Xss<size> set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
516 #if defined(ENABLE_PROFILING)
517 puts(" -Xprof[:bb] collect and print profiling data");
520 #if defined(ENABLE_JVMTI)
521 /* -Xdebug option depend on gnu classpath JDWP options. options:
522 transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
523 puts(" -Xdebug enable remote debugging\n");
524 puts(" -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
525 puts(" enable remote debugging\n");
528 /* exit with error code */
534 static void XXusage(void)
536 puts(" -v write state-information");
538 puts(" -verbose[:jit|threads]");
539 puts(" enable specific verbose output");
540 puts(" -debug-color colored output for ANSI terms");
542 #ifdef TYPECHECK_VERBOSE
543 puts(" -verbosetc write debug messages while typechecking");
545 #if defined(__ALPHA__)
546 puts(" -noieee don't use ieee compliant arithmetic");
548 #if defined(ENABLE_VERIFIER)
549 puts(" -noverify don't verify classfiles");
551 #if defined(ENABLE_STATISTICS)
552 puts(" -time measure the runtime");
553 puts(" -stat detailed compiler statistics");
555 puts(" -log logfile specify a name for the logfile");
556 puts(" -c(heck)b(ounds) don't check array bounds");
557 puts(" s(ync) don't check for synchronization");
558 #if defined(ENABLE_LOOP)
559 puts(" -oloop optimize array accesses in loops");
561 puts(" -l don't start the class after loading");
563 puts(" -all compile all methods, no execution");
564 puts(" -m compile only a specific method");
565 puts(" -sig specify signature for a specific method");
568 puts(" -s... show...");
569 puts(" (c)onstants the constant pool");
570 puts(" (m)ethods class fields and methods");
571 puts(" (u)tf the utf - hash");
572 puts(" (i)ntermediate intermediate representation");
573 #if defined(ENABLE_DISASSEMBLER)
574 puts(" (a)ssembler disassembled listing");
575 puts(" n(o)ps show NOPs in disassembler output");
576 puts(" (e)xceptionstubs disassembled exception stubs (only with -sa)");
577 puts(" (n)ative disassembled native stubs");
579 puts(" (d)atasegment data segment listing");
581 #if defined(ENABLE_INLINING)
582 puts(" -i activate inlining");
584 puts(" -il log inlining");
586 #if defined(ENABLE_INLINING_DEBUG)
587 puts(" -ia use inlining for all methods");
588 puts(" -ii <size> set minimum size for inlined result");
589 puts(" -im <size> set maximum size for inlined result");
590 puts(" -ie <number> stop inlining after the given number of roots");
591 #endif /* defined(ENABLE_INLINING_DEBUG) */
592 #endif /* defined(ENABLE_INLINING) */
594 #if defined(ENABLE_IFCONV)
595 puts(" -ifconv use if-conversion");
597 #if defined(ENABLE_LSRA)
598 puts(" -lsra use linear scan register allocation");
600 #if defined(ENABLE_SSA)
601 puts(" -lsra use linear scan register allocation (with SSA)");
603 #if defined(ENABLE_DEBUG_FILTER)
604 puts(" -XXfi <regex> begin of dynamic scope for verbosecall filter");
605 puts(" -XXfx <regex> end of dynamic scope for verbosecall filter");
606 puts(" -XXfm <regex> filter for show options");
608 /* exit with error code */
614 /* version *********************************************************************
616 Only prints cacao version information.
618 *******************************************************************************/
620 static void version(bool opt_exit)
622 puts("java version \""JAVA_VERSION"\"");
623 puts("CACAO version "VERSION"");
625 puts("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,");
626 puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
627 puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
628 puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
630 puts("This program is free software; you can redistribute it and/or");
631 puts("modify it under the terms of the GNU General Public License as");
632 puts("published by the Free Software Foundation; either version 2, or (at");
633 puts("your option) any later version.\n");
635 puts("This program is distributed in the hope that it will be useful, but");
636 puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
637 puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU");
638 puts("General Public License for more details.");
640 /* exit normally, if requested */
647 /* fullversion *****************************************************************
649 Prints a Sun compatible version information (required e.g. by
650 jpackage, www.jpackage.org).
652 *******************************************************************************/
654 static void fullversion(void)
656 puts("java full version \"cacao-"JAVA_VERSION"\"");
664 void vm_printconfig(void)
666 puts("Configure/Build options:\n");
667 puts(" ./configure: "VERSION_CONFIGURE_ARGS"");
668 #if defined(__VERSION__)
669 puts(" CC : "VERSION_CC" ("__VERSION__")");
671 puts(" CC : "VERSION_CC"");
673 puts(" CFLAGS : "VERSION_CFLAGS"\n");
675 puts("Default variables:\n");
676 printf(" maximum heap size : %d\n", HEAP_MAXSIZE);
677 printf(" initial heap size : %d\n", HEAP_STARTSIZE);
678 printf(" stack size : %d\n", STACK_SIZE);
679 #if defined(WITH_CLASSPATH_GNU)
680 puts(" java.boot.class.path : "CACAO_VM_ZIP":"CLASSPATH_CLASSES"");
682 puts(" java.boot.class.path : "CLASSPATH_CLASSES"");
684 puts(" gnu.classpath.boot.library.path: "CLASSPATH_LIBDIR"/classpath\n");
686 puts("Runtime variables:\n");
687 printf(" maximum heap size : %d\n", opt_heapmaxsize);
688 printf(" initial heap size : %d\n", opt_heapstartsize);
689 printf(" stack size : %d\n", opt_stacksize);
690 printf(" libjvm.so : %s\n", cacao_libjvm);
691 printf(" java.boot.class.path : %s\n", _Jv_bootclasspath);
692 printf(" gnu.classpath.boot.library.path: %s\n", classpath_libdir);
693 printf(" java.class.path : %s\n", _Jv_classpath);
697 /* forward declarations *******************************************************/
699 static char *vm_get_mainclass_from_jar(char *mainstring);
701 static void vm_compile_all(void);
702 static void vm_compile_method(void);
706 /* vm_createjvm ****************************************************************
708 Implementation for JNI_CreateJavaVM.
710 *******************************************************************************/
712 bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args)
714 JavaVMInitArgs *_vm_args;
718 /* get the arguments for the new JVM */
720 _vm_args = (JavaVMInitArgs *) vm_args;
722 /* get the VM and Env tables (must be set before vm_create) */
724 env = NEW(_Jv_JNIEnv);
726 #if defined(ENABLE_JNI)
727 env->env = &_Jv_JNINativeInterface;
730 /* XXX Set the global variable. Maybe we should do that differently. */
734 /* create and fill a JavaVM structure */
736 vm = NEW(_Jv_JavaVM);
738 #if defined(ENABLE_JNI)
739 vm->functions = &_Jv_JNIInvokeInterface;
742 /* XXX Set the global variable. Maybe we should do that differently. */
743 /* XXX JVMTI Agents needs a JavaVM */
747 /* actually create the JVM */
749 if (!vm_create(_vm_args))
752 #if defined(ENABLE_JNI)
753 /* setup the local ref table (must be created after vm_create) */
755 if (!jni_init_localref_table())
759 /* now return the values */
761 *p_vm = (JavaVM *) vm;
762 *p_env = (void *) env;
767 /* release allocated memory */
769 FREE(env, _Jv_JNIEnv);
770 FREE(vm, _Jv_JavaVM);
776 /* vm_create *******************************************************************
778 Creates a JVM. Called by vm_createjvm.
780 *******************************************************************************/
782 bool vm_create(JavaVMInitArgs *vm_args)
791 #if defined(ENABLE_JVMTI)
793 char *libname, *agentarg;
794 bool jdwp,agentbypath;
795 jdwp = agentbypath = false;
798 #if defined(ENABLE_VMLOG)
799 vmlog_cacao_init(vm_args);
802 /* check the JNI version requested */
804 switch (vm_args->version) {
805 case JNI_VERSION_1_1:
807 case JNI_VERSION_1_2:
808 case JNI_VERSION_1_4:
814 /* we only support 1 JVM instance */
819 if (atexit(vm_exit_handler))
820 vm_abort("atexit failed: %s\n", strerror(errno));
823 log_text("CACAO started -------------------------------------------------------");
825 /* We need to check if the actual size of a java.lang.Class object
826 is smaller or equal than the assumption made in
827 src/vmcore/class.h. */
829 if (sizeof(java_lang_Class) > sizeof(dummy_java_lang_Class))
830 vm_abort("vm_create: java_lang_Class structure is bigger than classinfo.object (%d > %d)", sizeof(java_lang_Class), sizeof(dummy_java_lang_Class));
832 /* set the VM starttime */
834 _Jv_jvm->starttime = builtin_currenttimemillis();
836 /* get stuff from the environment *****************************************/
838 #if defined(WITH_JRE_LAYOUT)
839 /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
841 cacao_prefix = MNEW(char, 4096);
843 if (readlink("/proc/self/exe", cacao_prefix, 4095) == -1)
844 vm_abort("readlink failed: %s\n", strerror(errno));
846 /* get the path of the current executable */
848 cacao_prefix = dirname(cacao_prefix);
850 if ((strlen(cacao_prefix) + strlen("/..") + strlen("0")) > 4096)
851 vm_abort("libjvm name to long for buffer\n");
853 /* concatenate the library name */
855 strcat(cacao_prefix, "/..");
857 /* now set path to libjvm.so */
859 len = strlen(cacao_prefix) + strlen("/lib/libjvm") + strlen("0");
861 cacao_libjvm = MNEW(char, len);
862 strcpy(cacao_libjvm, cacao_prefix);
863 strcat(cacao_libjvm, "/lib/libjvm");
865 /* and finally set the path to GNU Classpath libraries */
867 len = strlen(cacao_prefix) + strlen("/lib/classpath") + strlen("0");
869 classpath_libdir = MNEW(char, len);
870 strcpy(classpath_libdir, cacao_prefix);
871 strcat(classpath_libdir, "/lib/classpath");
873 cacao_prefix = CACAO_PREFIX;
874 cacao_libjvm = CACAO_LIBDIR"/libjvm";
876 # if defined(WITH_CLASSPATH_GNU)
877 classpath_libdir = CLASSPATH_LIBDIR"/classpath";
879 classpath_libdir = CLASSPATH_LIBDIR;
883 /* set the bootclasspath */
885 cp = getenv("BOOTCLASSPATH");
888 _Jv_bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
889 strcpy(_Jv_bootclasspath, cp);
892 #if defined(WITH_JRE_LAYOUT)
894 # if defined(WITH_CLASSPATH_GNU)
895 strlen(cacao_prefix) +
896 strlen("/share/cacao/vm.zip") +
899 strlen(cacao_prefix) +
900 strlen("/share/classpath/glibj.zip") +
903 _Jv_bootclasspath = MNEW(char, len);
904 # if defined(WITH_CLASSPATH_GNU)
905 strcat(_Jv_bootclasspath, cacao_prefix);
906 strcat(_Jv_bootclasspath, "/share/cacao/vm.zip");
907 strcat(_Jv_bootclasspath, ":");
909 strcat(_Jv_bootclasspath, cacao_prefix);
910 strcat(_Jv_bootclasspath, "/share/classpath/glibj.zip");
912 # if defined(WITH_CLASSPATH_GNU)
914 strlen(CACAO_VM_ZIP) +
916 strlen(CLASSPATH_CLASSES) +
918 # elif defined(WITH_CLASSPATH_SUN)
919 /* This is the bootclasspath taken from HotSpot (see
920 hotspot/src/share/vm/runtime/os.cpp
921 (os::set_boot_path)). */
924 strlen(CLASSPATH_PREFIX"/lib/resources.jar:"
925 CLASSPATH_PREFIX"/lib/rt.jar:"
926 CLASSPATH_PREFIX"/lib/sunrsasign.jar:"
927 CLASSPATH_PREFIX"/lib/jsse.jar:"
928 CLASSPATH_PREFIX"/lib/jce.jar:"
929 CLASSPATH_PREFIX"/lib/charsets.jar:"
930 CLASSPATH_PREFIX"/classes") +
932 # elif defined(WITH_CLASSPATH_CLDC1_1)
934 strlen(CLASSPATH_CLASSES) +
937 # error unknown classpath configuration
940 _Jv_bootclasspath = MNEW(char, len);
942 # if defined(WITH_CLASSPATH_GNU)
943 strcpy(_Jv_bootclasspath, CACAO_VM_ZIP);
944 strcat(_Jv_bootclasspath, ":");
945 strcat(_Jv_bootclasspath, CLASSPATH_CLASSES);
946 # elif defined(WITH_CLASSPATH_SUN)
947 strcpy(_Jv_bootclasspath,
948 CLASSPATH_PREFIX"/lib/resources.jar:"
949 CLASSPATH_PREFIX"/lib/rt.jar:"
950 CLASSPATH_PREFIX"/lib/sunrsasign.jar:"
951 CLASSPATH_PREFIX"/lib/jsse.jar:"
952 CLASSPATH_PREFIX"/lib/jce.jar:"
953 CLASSPATH_PREFIX"/lib/charsets.jar:"
954 CLASSPATH_PREFIX"/classes");
955 # elif defined(WITH_CLASSPATH_CLDC1_1)
956 strcat(_Jv_bootclasspath, CLASSPATH_CLASSES);
958 # error unknown classpath configuration
963 /* set the classpath */
965 cp = getenv("CLASSPATH");
968 _Jv_classpath = MNEW(char, strlen(cp) + strlen("0"));
969 strcat(_Jv_classpath, cp);
972 _Jv_classpath = MNEW(char, strlen(".") + strlen("0"));
973 strcpy(_Jv_classpath, ".");
976 /* Get and set java.library.path. */
978 _Jv_java_library_path = getenv("LD_LIBRARY_PATH");
980 if (_Jv_java_library_path == NULL)
981 _Jv_java_library_path = "";
983 /* interpret the options **************************************************/
990 opt_heapmaxsize = HEAP_MAXSIZE;
991 opt_heapstartsize = HEAP_STARTSIZE;
992 opt_stacksize = STACK_SIZE;
995 #if defined(ENABLE_JVMTI)
996 /* initialize JVMTI related **********************************************/
1000 /* Initialize and fill properties before command-line handling. */
1002 if (!properties_init())
1003 vm_abort("vm_create: properties_init failed");
1005 /* Set the classpath properties. */
1007 #if defined(ENABLE_JAVASE)
1008 properties_add("java.boot.class.path", _Jv_bootclasspath);
1009 properties_add("sun.boot.class.path", _Jv_bootclasspath);
1010 properties_add("java.class.path", _Jv_classpath);
1013 /* iterate over all passed options */
1015 while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
1029 #if SIZEOF_VOID_P == 8
1030 puts("Running a 32-bit JVM is not supported on this platform.");
1036 #if SIZEOF_VOID_P == 4
1037 puts("Running a 64-bit JVM is not supported on this platform.");
1043 /* forget old classpath and set the argument as new classpath */
1044 MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
1046 _Jv_classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
1047 strcpy(_Jv_classpath, opt_arg);
1049 #if defined(ENABLE_JAVASE)
1050 properties_add("java.class.path", _Jv_classpath);
1055 for (i = 0; i < strlen(opt_arg); i++) {
1056 if (opt_arg[i] == '=') {
1058 properties_add(opt_arg, opt_arg + i + 1);
1063 /* if no '=' is given, just create an empty property */
1065 properties_add(opt_arg, "");
1070 case OPT_BOOTCLASSPATH:
1071 /* Forget default bootclasspath and set the argument as
1072 new boot classpath. */
1074 MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
1076 _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
1077 strcpy(_Jv_bootclasspath, opt_arg);
1079 #if defined(ENABLE_JAVASE)
1080 properties_add("java.boot.class.path", _Jv_bootclasspath);
1081 properties_add("sun.boot.class.path", _Jv_bootclasspath);
1085 case OPT_BOOTCLASSPATH_A:
1086 /* append to end of bootclasspath */
1088 len = strlen(_Jv_bootclasspath);
1090 _Jv_bootclasspath = MREALLOC(_Jv_bootclasspath,
1094 strlen(opt_arg) + strlen("0"));
1096 strcat(_Jv_bootclasspath, ":");
1097 strcat(_Jv_bootclasspath, opt_arg);
1099 #if defined(ENABLE_JAVASE)
1100 properties_add("java.boot.class.path", _Jv_bootclasspath);
1101 properties_add("sun.boot.class.path", _Jv_bootclasspath);
1105 case OPT_BOOTCLASSPATH_P:
1106 /* prepend in front of bootclasspath */
1108 cp = _Jv_bootclasspath;
1111 _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
1114 strcpy(_Jv_bootclasspath, opt_arg);
1115 strcat(_Jv_bootclasspath, ":");
1116 strcat(_Jv_bootclasspath, cp);
1118 MFREE(cp, char, len);
1120 #if defined(ENABLE_JAVASE)
1121 properties_add("java.boot.class.path", _Jv_bootclasspath);
1122 properties_add("sun.boot.class.path", _Jv_bootclasspath);
1126 case OPT_BOOTCLASSPATH_C:
1127 /* use as Java core library, but prepend VM interface classes */
1129 MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
1131 len = strlen(CACAO_VM_ZIP) +
1136 _Jv_bootclasspath = MNEW(char, len);
1138 strcpy(_Jv_bootclasspath, CACAO_VM_ZIP);
1139 strcat(_Jv_bootclasspath, ":");
1140 strcat(_Jv_bootclasspath, opt_arg);
1142 #if defined(ENABLE_JAVASE)
1143 properties_add("java.boot.class.path", _Jv_bootclasspath);
1144 properties_add("sun.boot.class.path", _Jv_bootclasspath);
1148 #if defined(ENABLE_JVMTI)
1150 /* this option exists only for compatibility reasons */
1154 /* I don't know yet what Xnoagent should do. This is only for
1155 compatiblity with eclipse - motse */
1164 strlen(CACAO_LIBDIR) +
1165 strlen("/libjdwp.so=") +
1169 agentarg = MNEW(char, len);
1171 strcpy(agentarg, CACAO_LIBDIR);
1172 strcat(agentarg, "/libjdwp.so=");
1173 strcat(agentarg, &opt_arg[1]);
1190 c = opt_arg[strlen(opt_arg) - 1];
1192 if ((c == 'k') || (c == 'K')) {
1193 j = atoi(opt_arg) * 1024;
1195 } else if ((c == 'm') || (c == 'M')) {
1196 j = atoi(opt_arg) * 1024 * 1024;
1202 opt_heapmaxsize = j;
1203 else if (opt == OPT_MS)
1204 opt_heapstartsize = j;
1215 if (strcmp("class", opt_arg) == 0) {
1216 opt_verboseclass = true;
1218 else if (strcmp("gc", opt_arg) == 0) {
1219 opt_verbosegc = true;
1221 else if (strcmp("jni", opt_arg) == 0) {
1222 opt_verbosejni = true;
1224 #if !defined(NDEBUG)
1225 else if (strcmp("jit", opt_arg) == 0) {
1230 compileverbose = true;
1232 else if (strcmp("threads", opt_arg) == 0) {
1233 opt_verbosethreads = true;
1237 printf("Unknown -verbose option: %s\n", opt_arg);
1242 case OPT_DEBUGCOLOR:
1243 opt_debugcolor = true;
1246 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
1248 opt_typecheckverbose = true;
1257 case OPT_FULLVERSION:
1261 case OPT_SHOWVERSION:
1269 #if defined(ENABLE_VERIFIER)
1275 #if defined(ENABLE_STATISTICS)
1277 opt_getcompilingtime = true;
1278 opt_getloadingtime = true;
1291 for (i = 0; i < strlen(opt_arg); i++) {
1292 switch (opt_arg[i]) {
1294 checkbounds = false;
1307 makeinitializations = false;
1310 #if !defined(NDEBUG)
1314 makeinitializations = false;
1319 opt_method = opt_arg;
1320 makeinitializations = false;
1324 opt_signature = opt_arg;
1328 case OPT_SHOW: /* Display options */
1329 for (i = 0; i < strlen(opt_arg); i++) {
1330 switch (opt_arg[i]) {
1332 showconstantpool = true;
1344 opt_showintermediate = true;
1345 compileverbose = true;
1348 #if defined(ENABLE_DISASSEMBLER)
1350 opt_showdisassemble = true;
1351 compileverbose = true;
1355 opt_shownops = true;
1359 opt_showexceptionstubs = true;
1363 opt_shownativestub = true;
1368 opt_showddatasegment = true;
1377 #if defined(ENABLE_LOOP)
1383 #if defined(ENABLE_INLINING)
1384 #if defined(ENABLE_INLINING_DEBUG)
1385 case OPT_INLINE_DEBUG_ALL:
1386 opt_inline_debug_all = true;
1388 case OPT_INLINE_DEBUG_END:
1389 opt_inline_debug_end_counter = atoi(opt_arg);
1391 case OPT_INLINE_DEBUG_MIN:
1392 opt_inline_debug_min_size = atoi(opt_arg);
1394 case OPT_INLINE_DEBUG_MAX:
1395 opt_inline_debug_max_size = atoi(opt_arg);
1397 #endif /* defined(ENABLE_INLINING_DEBUG) */
1398 #if !defined(NDEBUG)
1399 case OPT_INLINE_LOG:
1400 opt_inline_debug_log = true;
1402 #endif /* !defined(NDEBUG) */
1405 opt_inlining = true;
1407 #endif /* defined(ENABLE_INLINING) */
1409 #if defined(ENABLE_IFCONV)
1415 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1430 options_xx(opt_arg);
1434 /* currently ignored */
1438 /* currently ignored */
1442 _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true;
1446 _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = false;
1449 #if defined(ENABLE_PROFILING)
1450 case OPT_PROF_OPTION:
1451 /* use <= to get the last \0 too */
1453 for (i = 0, j = 0; i <= strlen(opt_arg); i++) {
1454 if (opt_arg[i] == ',')
1457 if (opt_arg[i] == '\0') {
1458 if (strcmp("bb", opt_arg + j) == 0)
1462 printf("Unknown option: -Xprof:%s\n", opt_arg + j);
1466 /* set k to next char */
1479 #if defined(ENABLE_JIT)
1482 printf("-Xjit option not enabled.\n");
1488 #if defined(ENABLE_INTRP)
1491 printf("-Xint option not enabled.\n");
1496 #if defined(ENABLE_INTRP)
1497 case OPT_STATIC_SUPERS:
1498 opt_static_supers = atoi(opt_arg);
1501 case OPT_NO_DYNAMIC:
1502 opt_no_dynamic = true;
1505 case OPT_NO_REPLICATION:
1506 opt_no_replication = true;
1509 case OPT_NO_QUICKSUPER:
1510 opt_no_quicksuper = true;
1518 #if defined(ENABLE_DEBUG_FILTER)
1519 case OPT_FILTER_VERBOSECALL_INCLUDE:
1520 opt_filter_verbosecall_include = opt_arg;
1523 case OPT_FILTER_VERBOSECALL_EXCLUDE:
1524 opt_filter_verbosecall_exclude = opt_arg;
1527 case OPT_FILTER_SHOW_METHOD:
1528 opt_filter_show_method = opt_arg;
1533 printf("Unknown option: %s\n",
1534 vm_args->options[opt_index].optionString);
1539 /* get the main class *****************************************************/
1541 if (opt_index < vm_args->nOptions) {
1542 mainstring = vm_args->options[opt_index++].optionString;
1544 /* Put the jar file into the classpath (if any). */
1546 if (opt_jar == true) {
1547 /* free old classpath */
1549 MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
1551 /* put jarfile into classpath */
1553 _Jv_classpath = MNEW(char, strlen(mainstring) + strlen("0"));
1555 strcpy(_Jv_classpath, mainstring);
1557 #if defined(ENABLE_JAVASE)
1558 properties_add("java.class.path", _Jv_classpath);
1562 /* replace .'s with /'s in classname */
1564 for (i = strlen(mainstring) - 1; i >= 0; i--)
1565 if (mainstring[i] == '.')
1566 mainstring[i] = '/';
1570 #if defined(ENABLE_JVMTI)
1572 jvmti_set_phase(JVMTI_PHASE_ONLOAD);
1573 jvmti_agentload(agentarg, agentbypath, &handle, &libname);
1576 MFREE(agentarg, char, strlen(agentarg));
1578 jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
1582 /* initialize this JVM ****************************************************/
1584 vm_initializing = true;
1586 /* initialize the garbage collector */
1588 gc_init(opt_heapmaxsize, opt_heapstartsize);
1590 #if defined(ENABLE_THREADS)
1591 /* AFTER: gc_init (directly after, as this initializes the
1592 stopworldlock lock */
1597 /* install architecture dependent signal handlers */
1600 vm_abort("vm_create: signal_init failed");
1602 #if defined(ENABLE_INTRP)
1603 /* Allocate main thread stack on the Java heap. */
1606 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1607 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1611 /* AFTER: threads_preinit */
1614 vm_abort("vm_create: string_init failed");
1616 /* AFTER: threads_preinit */
1619 vm_abort("vm_create: utf8_init failed");
1621 /* AFTER: thread_preinit */
1624 vm_abort("vm_create: suck_init failed");
1626 suck_add_from_property("java.endorsed.dirs");
1628 /* Now we have all options handled and we can print the version
1631 AFTER: suck_add_from_property("java.endorsed.dirs"); */
1636 /* AFTER: utf8_init */
1638 suck_add(_Jv_bootclasspath);
1640 /* initialize the classcache hashtable stuff: lock, hashtable
1641 (must be done _after_ threads_preinit) */
1643 if (!classcache_init())
1644 vm_abort("vm_create: classcache_init failed");
1646 /* initialize the memory subsystem (must be done _after_
1650 vm_abort("vm_create: memory_init failed");
1652 /* initialize the finalizer stuff (must be done _after_
1655 if (!finalizer_init())
1656 vm_abort("vm_create: finalizer_init failed");
1658 /* initialize the codegen subsystems */
1662 /* initializes jit compiler */
1666 /* machine dependent initialization */
1668 #if defined(ENABLE_JIT)
1669 # if defined(ENABLE_INTRP)
1679 /* initialize the loader subsystems (must be done _after_
1683 vm_abort("vm_create: loader_init failed");
1685 /* Link some important VM classes. */
1686 /* AFTER: utf8_init */
1689 vm_abort("vm_create: linker_init failed");
1691 if (!primitive_init())
1692 vm_abort("vm_create: primitive_init failed");
1694 if (!exceptions_init())
1695 vm_abort("vm_create: exceptions_init failed");
1697 if (!builtin_init())
1698 vm_abort("vm_create: builtin_init failed");
1700 /* Initialize the native subsystem. */
1701 /* BEFORE: threads_init */
1704 vm_abort("vm_create: native_init failed");
1706 /* Register the native methods implemented in the VM. */
1707 /* BEFORE: threads_init */
1709 if (!nativevm_preinit())
1710 vm_abort("vm_create: nativevm_preinit failed");
1712 #if defined(ENABLE_JNI)
1713 /* Initialize the JNI subsystem (must be done _before_
1714 threads_init, as threads_init can call JNI methods
1715 (e.g. NewGlobalRef). */
1718 vm_abort("vm_create: jni_init failed");
1721 #if defined(ENABLE_THREADS)
1722 if (!threads_init())
1723 vm_abort("vm_create: threads_init failed");
1726 /* Initialize the native VM subsystem. */
1727 /* AFTER: threads_init (at least for SUN's classes) */
1729 if (!nativevm_init())
1730 vm_abort("vm_create: nativevm_init failed");
1732 #if defined(ENABLE_PROFILING)
1733 /* initialize profiling */
1735 if (!profile_init())
1736 vm_abort("vm_create: profile_init failed");
1739 #if defined(ENABLE_THREADS)
1740 /* initialize recompilation */
1742 if (!recompile_init())
1743 vm_abort("vm_create: recompile_init failed");
1745 /* start the signal handler thread */
1747 #if defined(__LINUX__)
1748 /* XXX Remove for exact-GC. */
1749 if (threads_pthreads_implementation_nptl)
1751 if (!signal_start_thread())
1752 vm_abort("vm_create: signal_start_thread failed");
1754 /* finally, start the finalizer thread */
1756 if (!finalizer_start_thread())
1757 vm_abort("vm_create: finalizer_start_thread failed");
1759 # if !defined(NDEBUG)
1760 /* start the memory profiling thread */
1762 if (opt_ProfileMemoryUsage || opt_ProfileGCMemoryUsage)
1763 if (!memory_start_thread())
1764 vm_abort("vm_create: memory_start_thread failed");
1767 /* start the recompilation thread (must be done before the
1768 profiling thread) */
1770 if (!recompile_start_thread())
1771 vm_abort("vm_create: recompile_start_thread failed");
1773 # if defined(ENABLE_PROFILING)
1774 /* start the profile sampling thread */
1777 /* if (!profile_start_thread()) */
1778 /* vm_abort("vm_create: profile_start_thread failed"); */
1782 #if defined(ENABLE_JVMTI)
1784 /* add agent library to native library hashtable */
1785 native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
1789 /* increment the number of VMs */
1793 /* initialization is done */
1795 vm_initializing = false;
1797 /* everything's ok */
1803 /* vm_run **********************************************************************
1805 Runs the main-method of the passed class.
1807 *******************************************************************************/
1809 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
1812 classinfo *mainclass;
1813 java_objectheader *e;
1815 java_objectarray *oa;
1818 java_objectheader *s;
1822 #if !defined(NDEBUG)
1828 if (opt_method != NULL) {
1829 vm_compile_method();
1832 #endif /* !defined(NDEBUG) */
1834 /* should we run the main-method? */
1836 if (mainstring == NULL)
1839 /* set return value to OK */
1843 if (opt_jar == true) {
1844 /* open jar file with java.util.jar.JarFile */
1846 mainstring = vm_get_mainclass_from_jar(mainstring);
1848 if (mainstring == NULL)
1852 /* load the main class */
1854 mainutf = utf_new_char(mainstring);
1856 #if defined(ENABLE_JAVAME_CLDC1_1)
1857 mainclass = load_class_bootstrap(mainutf);
1859 mainclass = load_class_from_sysloader(mainutf);
1862 /* error loading class */
1864 e = exceptions_get_and_clear_exception();
1866 if ((e != NULL) || (mainclass == NULL)) {
1867 exceptions_throw_noclassdeffounderror_cause(e);
1868 exceptions_print_stacktrace();
1872 if (!link_class(mainclass)) {
1873 exceptions_print_stacktrace();
1877 /* find the `main' method of the main class */
1879 m = class_resolveclassmethod(mainclass,
1880 utf_new_char("main"),
1881 utf_new_char("([Ljava/lang/String;)V"),
1882 class_java_lang_Object,
1885 if (exceptions_get_exception()) {
1886 exceptions_print_stacktrace();
1890 /* there is no main method or it isn't static */
1892 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
1893 exceptions_clear_exception();
1894 exceptions_throw_nosuchmethoderror(mainclass,
1895 utf_new_char("main"),
1896 utf_new_char("([Ljava/lang/String;)V"));
1898 exceptions_print_stacktrace();
1902 /* build argument array */
1904 oalength = vm_args->nOptions - opt_index;
1906 oa = builtin_anewarray(oalength, class_java_lang_String);
1908 for (i = 0; i < oalength; i++) {
1909 u = utf_new_char(vm_args->options[opt_index + i].optionString);
1910 s = javastring_new(u);
1915 #ifdef TYPEINFO_DEBUG_TEST
1916 /* test the typeinfo system */
1919 /*class_showmethods(currentThread->group->header.vftbl->class); */
1921 #if defined(ENABLE_JVMTI)
1922 jvmti_set_phase(JVMTI_PHASE_LIVE);
1925 /* set ThreadMXBean variables */
1927 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1928 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1930 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1931 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1932 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1933 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1935 /* start the main thread */
1937 (void) vm_call_method(m, NULL, oa);
1939 /* exception occurred? */
1941 if (exceptions_get_exception()) {
1942 exceptions_print_stacktrace();
1946 /* unload the JavaVM */
1948 (void) vm_destroy(vm);
1956 /* vm_destroy ******************************************************************
1958 Unloads a Java VM and reclaims its resources.
1960 *******************************************************************************/
1962 s4 vm_destroy(JavaVM *vm)
1964 #if defined(ENABLE_THREADS)
1965 threads_join_all_threads();
1968 /* everything's ok */
1974 /* vm_exit *********************************************************************
1976 Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1978 *******************************************************************************/
1980 void vm_exit(s4 status)
1984 /* signal that we are exiting */
1988 assert(class_java_lang_System);
1989 assert(class_java_lang_System->state & CLASS_LOADED);
1991 #if defined(ENABLE_JVMTI)
1992 if (jvmti || (dbgcom!=NULL)) {
1993 jvmti_set_phase(JVMTI_PHASE_DEAD);
1994 if (jvmti) jvmti_agentunload();
1998 if (!link_class(class_java_lang_System)) {
1999 exceptions_print_stacktrace();
2003 /* call java.lang.System.exit(I)V */
2005 m = class_resolveclassmethod(class_java_lang_System,
2006 utf_new_char("exit"),
2008 class_java_lang_Object,
2012 exceptions_print_stacktrace();
2016 /* call the exit function with passed exit status */
2018 (void) vm_call_method(m, NULL, status);
2020 /* If we had an exception, just ignore the exception and exit with
2023 vm_shutdown(status);
2027 /* vm_shutdown *****************************************************************
2029 Terminates the system immediately without freeing memory explicitly
2030 (to be used only for abnormal termination).
2032 *******************************************************************************/
2034 void vm_shutdown(s4 status)
2037 #if defined(ENABLE_STATISTICS)
2038 || opt_getcompilingtime || opt_stat
2042 log_text("CACAO terminated by shutdown");
2043 dolog("Exit status: %d\n", (s4) status);
2047 #if defined(ENABLE_JVMTI)
2048 /* terminate cacaodbgserver */
2050 pthread_mutex_lock(&dbgcomlock);
2052 pthread_mutex_unlock(&dbgcomlock);
2053 jvmti_cacaodbgserver_quit();
2061 /* vm_exit_handler *************************************************************
2063 The exit_handler function is called upon program termination.
2065 ATTENTION: Don't free system resources here! Some threads may still
2066 be running as this is called from VMRuntime.exit(). The OS does the
2069 *******************************************************************************/
2071 void vm_exit_handler(void)
2073 #if !defined(NDEBUG)
2075 class_showmethods(mainclass);
2077 if (showconstantpool)
2078 class_showconstantpool(mainclass);
2083 # if defined(ENABLE_PROFILING)
2085 profile_printstats();
2087 #endif /* !defined(NDEBUG) */
2089 #if defined(ENABLE_RT_TIMING)
2090 rt_timing_print_time_stats(stderr);
2093 #if defined(ENABLE_CYCLES_STATS)
2094 builtin_print_cycles_stats(stderr);
2095 stacktrace_print_cycles_stats(stderr);
2099 #if defined(ENABLE_STATISTICS)
2100 || opt_getcompilingtime || opt_stat
2104 log_text("CACAO terminated");
2106 #if defined(ENABLE_STATISTICS)
2109 #ifdef TYPECHECK_STATISTICS
2110 typecheck_print_statistics(get_logfile());
2114 if (opt_getcompilingtime)
2116 #endif /* defined(ENABLE_STATISTICS) */
2118 /* vm_print_profile(stderr);*/
2122 /* vm_abort ********************************************************************
2124 Prints an error message and aborts the VM.
2126 *******************************************************************************/
2128 void vm_abort(const char *text, ...)
2132 /* print the log message */
2137 log_vprint(text, ap);
2142 /* now abort the VM */
2148 /* vm_get_mainclass_from_jar ***************************************************
2150 Gets the name of the main class from a JAR's manifest file.
2152 *******************************************************************************/
2154 static char *vm_get_mainclass_from_jar(char *mainstring)
2157 java_objectheader *o;
2159 java_objectheader *s;
2161 c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
2164 exceptions_print_stacktrace();
2168 /* create JarFile object */
2173 exceptions_print_stacktrace();
2177 m = class_resolveclassmethod(c,
2179 utf_java_lang_String__void,
2180 class_java_lang_Object,
2184 exceptions_print_stacktrace();
2188 s = javastring_new_from_ascii(mainstring);
2190 (void) vm_call_method(m, o, s);
2192 if (exceptions_get_exception()) {
2193 exceptions_print_stacktrace();
2197 /* get manifest object */
2199 m = class_resolveclassmethod(c,
2200 utf_new_char("getManifest"),
2201 utf_new_char("()Ljava/util/jar/Manifest;"),
2202 class_java_lang_Object,
2206 exceptions_print_stacktrace();
2210 o = vm_call_method(m, o);
2213 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
2218 /* get Main Attributes */
2220 m = class_resolveclassmethod(o->vftbl->class,
2221 utf_new_char("getMainAttributes"),
2222 utf_new_char("()Ljava/util/jar/Attributes;"),
2223 class_java_lang_Object,
2227 exceptions_print_stacktrace();
2231 o = vm_call_method(m, o);
2234 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
2239 /* get property Main-Class */
2241 m = class_resolveclassmethod(o->vftbl->class,
2242 utf_new_char("getValue"),
2243 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
2244 class_java_lang_Object,
2248 exceptions_print_stacktrace();
2252 s = javastring_new_from_ascii("Main-Class");
2254 o = vm_call_method(m, o, s);
2257 exceptions_print_stacktrace();
2261 return javastring_tochar(o);
2265 /* vm_compile_all **************************************************************
2267 Compile all methods found in the bootclasspath.
2269 *******************************************************************************/
2271 #if !defined(NDEBUG)
2272 static void vm_compile_all(void)
2277 classcache_name_entry *nmen;
2278 classcache_class_entry *clsen;
2281 /* create all classes found in the bootclasspath */
2282 /* XXX currently only works with zip/jar's */
2284 loader_load_all_classes();
2286 /* link all classes */
2288 for (slot = 0; slot < hashtable_classcache.size; slot++) {
2289 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
2291 for (; nmen; nmen = nmen->hashlink) {
2292 /* iterate over all class entries */
2294 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
2295 c = clsen->classobj;
2300 if (!(c->state & CLASS_LINKED)) {
2301 if (!link_class(c)) {
2302 fprintf(stderr, "Error linking: ");
2303 utf_fprint_printable_ascii_classname(stderr, c->name);
2304 fprintf(stderr, "\n");
2306 /* print out exception and cause */
2308 exceptions_print_current_exception();
2310 /* goto next class */
2316 /* compile all class methods */
2318 for (i = 0; i < c->methodscount; i++) {
2319 m = &(c->methods[i]);
2321 if (m->jcode != NULL) {
2322 if (!jit_compile(m)) {
2323 fprintf(stderr, "Error compiling: ");
2324 utf_fprint_printable_ascii_classname(stderr, c->name);
2325 fprintf(stderr, ".");
2326 utf_fprint_printable_ascii(stderr, m->name);
2327 utf_fprint_printable_ascii(stderr, m->descriptor);
2328 fprintf(stderr, "\n");
2330 /* print out exception and cause */
2332 exceptions_print_current_exception();
2340 #endif /* !defined(NDEBUG) */
2343 /* vm_compile_method ***********************************************************
2345 Compile a specific method.
2347 *******************************************************************************/
2349 #if !defined(NDEBUG)
2350 static void vm_compile_method(void)
2354 /* create, load and link the main class */
2356 mainclass = load_class_bootstrap(utf_new_char(mainstring));
2358 if (mainclass == NULL)
2359 exceptions_print_stacktrace();
2361 if (!link_class(mainclass))
2362 exceptions_print_stacktrace();
2364 if (opt_signature != NULL) {
2365 m = class_resolveclassmethod(mainclass,
2366 utf_new_char(opt_method),
2367 utf_new_char(opt_signature),
2372 m = class_resolveclassmethod(mainclass,
2373 utf_new_char(opt_method),
2380 vm_abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
2381 opt_method, opt_signature ? opt_signature : "");
2385 #endif /* !defined(NDEBUG) */
2388 /* vm_array_store_int **********************************************************
2390 Helper function to store an integer into the argument array, taking
2391 care of architecture specific issues.
2393 *******************************************************************************/
2395 static void vm_array_store_int(uint64_t *array, paramdesc *pd, int32_t value)
2399 if (!pd->inmemory) {
2401 array[index] = (int64_t) value;
2404 index = ARG_CNT + pd->index;
2405 #if SIZEOF_VOID_P == 8
2406 array[index] = (int64_t) value;
2408 # if WORDS_BIGENDIAN == 1
2409 array[index] = ((int64_t) value) << 32;
2411 array[index] = (int64_t) value;
2418 /* vm_array_store_lng **********************************************************
2420 Helper function to store a long into the argument array, taking
2421 care of architecture specific issues.
2423 *******************************************************************************/
2425 static void vm_array_store_lng(uint64_t *array, paramdesc *pd, int64_t value)
2429 #if SIZEOF_VOID_P == 8
2433 index = ARG_CNT + pd->index;
2435 array[index] = value;
2437 if (!pd->inmemory) {
2438 /* move low and high 32-bits into it's own argument slot */
2440 index = GET_LOW_REG(pd->index);
2441 array[index] = value & 0x00000000ffffffff;
2443 index = GET_HIGH_REG(pd->index);
2444 array[index] = value >> 32;
2447 index = ARG_CNT + pd->index;
2448 array[index] = value;
2454 /* vm_array_store_flt **********************************************************
2456 Helper function to store a float into the argument array, taking
2457 care of architecture specific issues.
2459 *******************************************************************************/
2461 static void vm_array_store_flt(uint64_t *array, paramdesc *pd, uint64_t value)
2465 if (!pd->inmemory) {
2466 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2469 index = INT_ARG_CNT + pd->index;
2471 #if WORDS_BIGENDIAN == 1 && !defined(__POWERPC64__)
2472 array[index] = value >> 32;
2474 array[index] = value;
2478 index = ARG_CNT + pd->index;
2479 #if defined(__SPARC_64__)
2480 array[index] = value >> 32;
2482 array[index] = value;
2488 /* vm_array_store_dbl **********************************************************
2490 Helper function to store a double into the argument array, taking
2491 care of architecture specific issues.
2493 *******************************************************************************/
2495 static void vm_array_store_dbl(uint64_t *array, paramdesc *pd, uint64_t value)
2499 if (!pd->inmemory) {
2500 #if SIZEOF_VOID_P != 8 && defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2501 index = GET_LOW_REG(pd->index);
2502 array[index] = value & 0x00000000ffffffff;
2504 index = GET_HIGH_REG(pd->index);
2505 array[index] = value >> 32;
2507 index = INT_ARG_CNT + pd->index;
2508 array[index] = value;
2512 index = ARG_CNT + pd->index;
2513 array[index] = value;
2518 /* vm_array_store_adr **********************************************************
2520 Helper function to store an address into the argument array, taking
2521 care of architecture specific issues.
2523 *******************************************************************************/
2525 static void vm_array_store_adr(uint64_t *array, paramdesc *pd, void *value)
2529 if (!pd->inmemory) {
2530 #if defined(HAS_ADDRESS_REGISTER_FILE)
2531 /* When the architecture has address registers, place them
2532 after integer and float registers. */
2534 index = INT_ARG_CNT + FLT_ARG_CNT + pd->index;
2538 array[index] = (uint64_t) (intptr_t) value;
2541 index = ARG_CNT + pd->index;
2542 #if SIZEOF_VOID_P == 8
2543 array[index] = (uint64_t) (intptr_t) value;
2545 # if WORDS_BIGENDIAN == 1 && !defined(__POWERPC64__)
2546 array[index] = ((uint64_t) (intptr_t) value) << 32;
2548 array[index] = (uint64_t) (intptr_t) value;
2555 /* vm_vmargs_from_valist *******************************************************
2559 *******************************************************************************/
2561 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
2562 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
2563 vm_arg *vmargs, va_list ap)
2565 typedesc *paramtypes;
2568 paramtypes = m->parseddesc->paramtypes;
2570 /* if method is non-static fill first block and skip `this' pointer */
2575 /* the `this' pointer */
2576 vmargs[0].type = TYPE_ADR;
2577 vmargs[0].data.l = (u8) (ptrint) o;
2583 for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
2584 switch (paramtypes->type) {
2586 vmargs[i].type = TYPE_INT;
2587 vmargs[i].data.l = (s8) va_arg(ap, s4);
2591 vmargs[i].type = TYPE_LNG;
2592 vmargs[i].data.l = (s8) va_arg(ap, s8);
2596 vmargs[i].type = TYPE_FLT;
2597 #if defined(__ALPHA__)
2598 /* this keeps the assembler function much simpler */
2600 vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2602 vmargs[i].data.f = (jfloat) va_arg(ap, jdouble);
2607 vmargs[i].type = TYPE_DBL;
2608 vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2612 vmargs[i].type = TYPE_ADR;
2613 vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*);
2619 uint64_t *vm_array_from_valist(methodinfo *m, java_objectheader *o, va_list ap)
2628 /* get the descriptors */
2632 td = md->paramtypes;
2634 /* allocate argument array */
2636 array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
2638 /* if method is non-static fill first block and skip `this' pointer */
2643 /* the `this' pointer */
2644 vm_array_store_adr(array, pd, o);
2651 for (; i < md->paramcount; i++, pd++, td++) {
2654 value.i = va_arg(ap, int32_t);
2655 vm_array_store_int(array, pd, value.i);
2659 value.l = va_arg(ap, int64_t);
2660 vm_array_store_lng(array, pd, value.l);
2664 #if defined(__ALPHA__) || defined(__POWERPC64__)
2665 /* this keeps the assembler function much simpler */
2667 value.d = (double) va_arg(ap, double);
2669 value.f = (float) va_arg(ap, double);
2671 vm_array_store_flt(array, pd, value.l);
2675 value.d = va_arg(ap, double);
2676 vm_array_store_dbl(array, pd, value.l);
2680 value.a = va_arg(ap, void*);
2681 vm_array_store_adr(array, pd, value.a);
2691 /* vm_vmargs_from_jvalue *******************************************************
2695 *******************************************************************************/
2697 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
2698 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
2699 vm_arg *vmargs, const jvalue *args)
2701 typedesc *paramtypes;
2705 paramtypes = m->parseddesc->paramtypes;
2707 /* if method is non-static fill first block and skip `this' pointer */
2712 /* the `this' pointer */
2713 vmargs[0].type = TYPE_ADR;
2714 vmargs[0].data.l = (u8) (ptrint) o;
2720 for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
2721 switch (paramtypes->decltype) {
2723 vmargs[i].type = TYPE_INT;
2724 vmargs[i].data.l = (s8) args[j].i;
2728 vmargs[i].type = TYPE_LNG;
2729 vmargs[i].data.l = (s8) args[j].j;
2733 vmargs[i].type = TYPE_FLT;
2734 #if defined(__ALPHA__)
2735 /* this keeps the assembler function much simpler */
2737 vmargs[i].data.d = (jdouble) args[j].f;
2739 vmargs[i].data.f = args[j].f;
2744 vmargs[i].type = TYPE_DBL;
2745 vmargs[i].data.d = args[j].d;
2749 vmargs[i].type = TYPE_ADR;
2750 vmargs[i].data.l = (u8) (ptrint) args[j].l;
2756 static uint64_t *vm_array_from_jvalue(methodinfo *m, java_objectheader *o,
2766 /* get the descriptors */
2770 td = md->paramtypes;
2772 /* allocate argument array */
2774 #if defined(HAS_ADDRESS_REGISTER_FILE)
2775 array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + ADR_ARG_CNT + md->memuse);
2777 array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
2780 /* if method is non-static fill first block and skip `this' pointer */
2785 /* the `this' pointer */
2786 vm_array_store_adr(array, pd, o);
2793 for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
2794 switch (td->decltype) {
2796 vm_array_store_int(array, pd, args[j].i);
2800 vm_array_store_lng(array, pd, args[j].j);
2804 vm_array_store_flt(array, pd, args[j].j);
2808 vm_array_store_dbl(array, pd, args[j].j);
2812 vm_array_store_adr(array, pd, args[j].l);
2821 /* vm_vmargs_from_objectarray **************************************************
2825 *******************************************************************************/
2827 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
2828 bool vm_vmargs_from_objectarray(methodinfo *m, java_objectheader *o,
2829 vm_arg *vmargs, java_objectarray *params)
2831 java_objectheader *param;
2832 typedesc *paramtypes;
2838 paramtypes = m->parseddesc->paramtypes;
2840 /* if method is non-static fill first block and skip `this' pointer */
2846 vmargs[0].type = TYPE_ADR;
2847 vmargs[0].data.l = (uint64_t) (intptr_t) o;
2853 for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
2854 switch (paramtypes->type) {
2855 /* primitive types */
2860 param = params->data[j];
2865 /* internally used data type */
2866 vmargs[i].type = paramtypes->type;
2868 /* convert the value according to its declared type */
2870 c = param->vftbl->class;
2872 switch (paramtypes->decltype) {
2873 case PRIMITIVETYPE_BOOLEAN:
2874 if (c == class_java_lang_Boolean)
2875 value = (int64_t) ((java_lang_Boolean *) param)->value;
2879 vmargs[i].data.l = value;
2882 case PRIMITIVETYPE_BYTE:
2883 if (c == class_java_lang_Byte)
2884 value = (int64_t) ((java_lang_Byte *) param)->value;
2888 vmargs[i].data.l = value;
2891 case PRIMITIVETYPE_CHAR:
2892 if (c == class_java_lang_Character)
2893 value = (int64_t) ((java_lang_Character *) param)->value;
2897 vmargs[i].data.l = value;
2900 case PRIMITIVETYPE_SHORT:
2901 if (c == class_java_lang_Short)
2902 value = (int64_t) ((java_lang_Short *) param)->value;
2903 else if (c == class_java_lang_Byte)
2904 value = (int64_t) ((java_lang_Byte *) param)->value;
2908 vmargs[i].data.l = value;
2911 case PRIMITIVETYPE_INT:
2912 if (c == class_java_lang_Integer)
2913 value = (int64_t) ((java_lang_Integer *) param)->value;
2914 else if (c == class_java_lang_Short)
2915 value = (int64_t) ((java_lang_Short *) param)->value;
2916 else if (c == class_java_lang_Byte)
2917 value = (int64_t) ((java_lang_Byte *) param)->value;
2921 vmargs[i].data.l = value;
2924 case PRIMITIVETYPE_LONG:
2925 if (c == class_java_lang_Long)
2926 value = (int64_t) ((java_lang_Long *) param)->value;
2927 else if (c == class_java_lang_Integer)
2928 value = (int64_t) ((java_lang_Integer *) param)->value;
2929 else if (c == class_java_lang_Short)
2930 value = (int64_t) ((java_lang_Short *) param)->value;
2931 else if (c == class_java_lang_Byte)
2932 value = (int64_t) ((java_lang_Byte *) param)->value;
2936 vmargs[i].data.l = value;
2939 case PRIMITIVETYPE_FLOAT:
2940 if (c == class_java_lang_Float)
2941 vmargs[i].data.f = (jfloat) ((java_lang_Float *) param)->value;
2946 case PRIMITIVETYPE_DOUBLE:
2947 if (c == class_java_lang_Double)
2948 vmargs[i].data.d = (jdouble) ((java_lang_Double *) param)->value;
2949 else if (c == class_java_lang_Float)
2950 vmargs[i].data.f = (jfloat) ((java_lang_Float *) param)->value;
2961 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
2964 if (params->data[j] != 0) {
2965 if (paramtypes->arraydim > 0) {
2966 if (!builtin_arrayinstanceof(params->data[j], c))
2970 if (!builtin_instanceof(params->data[j], c))
2975 vmargs[i].type = TYPE_ADR;
2976 vmargs[i].data.l = (u8) (ptrint) params->data[j];
2985 /* *rettype = descr->returntype.decltype; */
2990 exceptions_throw_illegalargumentexception();
2994 uint64_t *vm_array_from_objectarray(methodinfo *m, java_objectheader *o,
2995 java_objectarray *params)
3001 java_objectheader *param;
3007 /* get the descriptors */
3011 td = md->paramtypes;
3013 /* allocate argument array */
3015 array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
3017 /* if method is non-static fill first block and skip `this' pointer */
3023 vm_array_store_adr(array, pd, o);
3030 for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
3031 param = params->data[j];
3038 /* convert the value according to its declared type */
3040 c = param->vftbl->class;
3042 switch (td->decltype) {
3043 case PRIMITIVETYPE_BOOLEAN:
3044 if (c == class_java_lang_Boolean)
3045 value.i = ((java_lang_Boolean *) param)->value;
3050 case PRIMITIVETYPE_BYTE:
3051 if (c == class_java_lang_Byte)
3052 value.i = ((java_lang_Byte *) param)->value;
3057 case PRIMITIVETYPE_CHAR:
3058 if (c == class_java_lang_Character)
3059 value.i = ((java_lang_Character *) param)->value;
3064 case PRIMITIVETYPE_SHORT:
3065 if (c == class_java_lang_Short)
3066 value.i = ((java_lang_Short *) param)->value;
3067 else if (c == class_java_lang_Byte)
3068 value.i = ((java_lang_Byte *) param)->value;
3073 case PRIMITIVETYPE_INT:
3074 if (c == class_java_lang_Integer)
3075 value.i = ((java_lang_Integer *) param)->value;
3076 else if (c == class_java_lang_Short)
3077 value.i = ((java_lang_Short *) param)->value;
3078 else if (c == class_java_lang_Byte)
3079 value.i = ((java_lang_Byte *) param)->value;
3088 vm_array_store_int(array, pd, value.i);
3095 /* convert the value according to its declared type */
3097 c = param->vftbl->class;
3099 switch (td->decltype) {
3100 case PRIMITIVETYPE_LONG:
3101 if (c == class_java_lang_Long)
3102 value.l = ((java_lang_Long *) param)->value;
3103 else if (c == class_java_lang_Integer)
3104 value.l = (int64_t) ((java_lang_Integer *) param)->value;
3105 else if (c == class_java_lang_Short)
3106 value.l = (int64_t) ((java_lang_Short *) param)->value;
3107 else if (c == class_java_lang_Byte)
3108 value.l = (int64_t) ((java_lang_Byte *) param)->value;
3117 vm_array_store_lng(array, pd, value.l);
3124 /* convert the value according to its declared type */
3126 c = param->vftbl->class;
3128 switch (td->decltype) {
3129 case PRIMITIVETYPE_FLOAT:
3130 if (c == class_java_lang_Float)
3131 value.f = ((java_lang_Float *) param)->value;
3140 vm_array_store_flt(array, pd, value.l);
3147 /* convert the value according to its declared type */
3149 c = param->vftbl->class;
3151 switch (td->decltype) {
3152 case PRIMITIVETYPE_DOUBLE:
3153 if (c == class_java_lang_Double)
3154 value.d = ((java_lang_Double *) param)->value;
3155 else if (c == class_java_lang_Float)
3156 value.f = ((java_lang_Float *) param)->value;
3165 vm_array_store_dbl(array, pd, value.l);
3169 if (!resolve_class_from_typedesc(td, true, true, &c))
3172 if (param != NULL) {
3173 if (td->arraydim > 0) {
3174 if (!builtin_arrayinstanceof(param, c))
3178 if (!builtin_instanceof(param, c))
3183 vm_array_store_adr(array, pd, param);
3194 exceptions_throw_illegalargumentexception();
3200 /* vm_call_method **************************************************************
3202 Calls a Java method with a variable number of arguments and returns
3205 *******************************************************************************/
3207 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
3210 java_objectheader *ro;
3213 ro = vm_call_method_valist(m, o, ap);
3220 /* vm_call_method_valist *******************************************************
3222 Calls a Java method with a variable number of arguments, passed via
3223 a va_list, and returns an address.
3225 *******************************************************************************/
3227 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
3230 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
3233 java_objectheader *ro;
3236 /* mark start of dump memory area */
3238 dumpsize = dump_size();
3240 /* get number of Java method arguments */
3242 vmargscount = m->parseddesc->paramcount;
3244 /* allocate vm_arg array */
3246 vmargs = DMNEW(vm_arg, vmargscount);
3248 /* fill the vm_arg array from a va_list */
3250 vm_vmargs_from_valist(m, o, vmargs, ap);
3252 /* call the Java method */
3254 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
3256 /* release dump area */
3258 dump_release(dumpsize);
3262 java_objectheader *ro;
3266 /* mark start of dump memory area */
3268 dumpsize = dump_size();
3270 /* fill the argument array from a va_list */
3272 array = vm_array_from_valist(m, o, ap);
3274 /* call the Java method */
3276 ro = vm_call_array(m, array);
3278 /* release dump area */
3280 dump_release(dumpsize);
3287 /* vm_call_method_jvalue *******************************************************
3289 Calls a Java method with a variable number of arguments, passed via
3290 a jvalue array, and returns an address.
3292 *******************************************************************************/
3294 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
3297 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
3300 java_objectheader *ro;
3303 /* mark start of dump memory area */
3305 dumpsize = dump_size();
3307 /* get number of Java method arguments */
3309 vmargscount = m->parseddesc->paramcount;
3311 /* allocate vm_arg array */
3313 vmargs = DMNEW(vm_arg, vmargscount);
3315 /* fill the vm_arg array from a va_list */
3317 vm_vmargs_from_jvalue(m, o, vmargs, args);
3319 /* call the Java method */
3321 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
3323 /* release dump area */
3325 dump_release(dumpsize);
3329 java_objectheader *ro;
3333 /* mark start of dump memory area */
3335 dumpsize = dump_size();
3337 /* fill the argument array from a va_list */
3339 array = vm_array_from_jvalue(m, o, args);
3341 /* call the Java method */
3343 ro = vm_call_array(m, array);
3345 /* release dump area */
3347 dump_release(dumpsize);
3354 /* vm_call_array ***************************************************************
3356 Calls a Java method with a variable number of arguments, passed via
3357 an argument array, and returns an address.
3359 *******************************************************************************/
3361 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
3362 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
3365 java_objectheader *o;
3367 STATISTICS(count_calls_native_to_java++);
3369 #if defined(ENABLE_JIT)
3370 # if defined(ENABLE_INTRP)
3372 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3375 o = asm_vm_call_method(m, vmargscount, vmargs);
3377 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3383 java_objectheader *vm_call_array(methodinfo *m, uint64_t *array)
3386 java_objectheader *o;
3390 /* compile the method if not already done */
3392 if (m->code == NULL)
3393 if (!jit_compile(m))
3396 STATISTICS(count_calls_native_to_java++);
3398 #if defined(ENABLE_JIT)
3399 # if defined(ENABLE_INTRP)
3401 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3404 o = asm_vm_call_method(m->code->entrypoint, array, md->memuse);
3406 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3414 /* vm_call_int_array ***********************************************************
3416 Calls a Java method with a variable number of arguments, passed via
3417 an argument array, and returns an integer (int32_t).
3419 *******************************************************************************/
3421 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
3422 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
3426 STATISTICS(count_calls_native_to_java++);
3428 #if defined(ENABLE_JIT)
3429 # if defined(ENABLE_INTRP)
3431 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3434 i = asm_vm_call_method_int(m, vmargscount, vmargs);
3436 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3442 int32_t vm_call_int_array(methodinfo *m, uint64_t *array)
3449 /* compile the method if not already done */
3451 if (m->code == NULL)
3452 if (!jit_compile(m))
3455 STATISTICS(count_calls_native_to_java++);
3457 #if defined(ENABLE_JIT)
3458 # if defined(ENABLE_INTRP)
3460 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3463 i = asm_vm_call_method_int(m->code->entrypoint, array, md->memuse);
3465 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3473 /* vm_call_method_int **********************************************************
3475 Calls a Java method with a variable number of arguments and returns
3478 *******************************************************************************/
3480 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
3486 i = vm_call_method_int_valist(m, o, ap);
3493 /* vm_call_method_int_valist ***************************************************
3495 Calls a Java method with a variable number of arguments, passed via
3496 a va_list, and returns an integer (int32_t).
3498 *******************************************************************************/
3500 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
3501 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
3508 /* mark start of dump memory area */
3510 dumpsize = dump_size();
3512 /* get number of Java method arguments */
3514 vmargscount = m->parseddesc->paramcount;
3516 /* allocate vm_arg array */
3518 vmargs = DMNEW(vm_arg, vmargscount);
3520 /* fill the vm_arg array from a va_list */
3522 vm_vmargs_from_valist(m, o, vmargs, ap);
3524 /* call the Java method */
3526 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
3528 /* release dump area */
3530 dump_release(dumpsize);
3535 int32_t vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
3541 /* mark start of dump memory area */
3543 dumpsize = dump_size();
3545 /* fill the argument array from a va_list */
3547 array = vm_array_from_valist(m, o, ap);
3549 /* call the Java method */
3551 i = vm_call_int_array(m, array);
3553 /* release dump area */
3555 dump_release(dumpsize);
3562 /* vm_call_method_int_jvalue ***************************************************
3564 Calls a Java method with a variable number of arguments, passed via
3565 a jvalue array, and returns an integer (s4).
3567 *******************************************************************************/
3569 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
3570 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o,
3578 /* mark start of dump memory area */
3580 dumpsize = dump_size();
3582 /* get number of Java method arguments */
3584 vmargscount = m->parseddesc->paramcount;
3586 /* allocate vm_arg array */
3588 vmargs = DMNEW(vm_arg, vmargscount);
3590 /* fill the vm_arg array from a va_list */
3592 vm_vmargs_from_jvalue(m, o, vmargs, args);
3594 /* call the Java method */
3596 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
3598 /* release dump area */
3600 dump_release(dumpsize);
3605 int32_t vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o,
3612 /* mark start of dump memory area */
3614 dumpsize = dump_size();
3616 /* fill the argument array from a va_list */
3618 array = vm_array_from_jvalue(m, o, args);
3620 /* call the Java method */
3622 i = vm_call_int_array(m, array);
3624 /* release dump area */
3626 dump_release(dumpsize);
3633 /* vm_call_long_array **********************************************************
3635 Calls a Java method with a variable number of arguments, passed via
3636 an argument array, and returns a long (int64_t).
3638 *******************************************************************************/
3640 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
3641 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
3645 STATISTICS(count_calls_native_to_java++);
3647 #if defined(ENABLE_JIT)
3648 # if defined(ENABLE_INTRP)
3650 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3653 l = asm_vm_call_method_long(m, vmargscount, vmargs);
3655 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3661 int64_t vm_call_long_array(methodinfo *m, uint64_t *array)
3668 /* compile the method if not already done */
3670 if (m->code == NULL)
3671 if (!jit_compile(m))
3674 STATISTICS(count_calls_native_to_java++);
3676 #if defined(ENABLE_JIT)
3677 # if defined(ENABLE_INTRP)
3679 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3682 l = asm_vm_call_method_long(m->code->entrypoint, array, md->memuse);
3684 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3692 /* vm_call_method_long *********************************************************
3694 Calls a Java method with a variable number of arguments and returns
3697 *******************************************************************************/
3699 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
3705 l = vm_call_method_long_valist(m, o, ap);
3712 /* vm_call_method_long_valist **************************************************
3714 Calls a Java method with a variable number of arguments, passed via
3715 a va_list, and returns a long (s8).
3717 *******************************************************************************/
3719 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
3720 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
3727 /* mark start of dump memory area */
3729 dumpsize = dump_size();
3731 /* get number of Java method arguments */
3733 vmargscount = m->parseddesc->paramcount;
3735 /* allocate vm_arg array */
3737 vmargs = DMNEW(vm_arg, vmargscount);
3739 /* fill the vm_arg array from a va_list */
3741 vm_vmargs_from_valist(m, o, vmargs, ap);
3743 /* call the Java method */
3745 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
3747 /* release dump area */
3749 dump_release(dumpsize);
3754 int64_t vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
3760 /* mark start of dump memory area */
3762 dumpsize = dump_size();
3764 /* fill the argument array from a va_list */
3766 array = vm_array_from_valist(m, o, ap);
3768 /* call the Java method */
3770 l = vm_call_long_array(m, array);
3772 /* release dump area */
3774 dump_release(dumpsize);
3781 /* vm_call_method_long_jvalue **************************************************
3783 Calls a Java method with a variable number of arguments, passed via
3784 a jvalue array, and returns a long (s8).
3786 *******************************************************************************/
3788 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
3789 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o,
3797 /* mark start of dump memory area */
3799 dumpsize = dump_size();
3801 /* get number of Java method arguments */
3803 vmargscount = m->parseddesc->paramcount;
3805 /* allocate vm_arg array */
3807 vmargs = DMNEW(vm_arg, vmargscount);
3809 /* fill the vm_arg array from a va_list */
3811 vm_vmargs_from_jvalue(m, o, vmargs, args);
3813 /* call the Java method */
3815 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
3817 /* release dump area */
3819 dump_release(dumpsize);
3824 int64_t vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o,
3831 /* mark start of dump memory area */
3833 dumpsize = dump_size();
3835 /* fill the argument array from a va_list */
3837 array = vm_array_from_jvalue(m, o, args);
3839 /* call the Java method */
3841 l = vm_call_long_array(m, array);
3843 /* release dump area */
3845 dump_release(dumpsize);
3852 /* vm_call_float_array *********************************************************
3854 Calls a Java method with a variable number of arguments and returns
3857 *******************************************************************************/
3859 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
3860 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
3864 vm_abort("IMPLEMENT ME!");
3866 STATISTICS(count_calls_native_to_java++);
3868 #if defined(ENABLE_JIT)
3869 # if defined(ENABLE_INTRP)
3871 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3874 f = asm_vm_call_method_float(m, vmargscount, vmargs);
3876 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3882 float vm_call_float_array(methodinfo *m, uint64_t *array)
3889 /* compile the method if not already done */
3891 if (m->code == NULL)
3892 if (!jit_compile(m))
3895 STATISTICS(count_calls_native_to_java++);
3897 #if defined(ENABLE_JIT)
3898 # if defined(ENABLE_INTRP)
3900 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3903 f = asm_vm_call_method_float(m->code->entrypoint, array, md->memuse);
3905 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3912 /* vm_call_method_float ********************************************************
3914 Calls a Java method with a variable number of arguments and returns
3917 *******************************************************************************/
3919 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
3925 f = vm_call_method_float_valist(m, o, ap);
3932 /* vm_call_method_float_valist *************************************************
3934 Calls a Java method with a variable number of arguments, passed via
3935 a va_list, and returns a float.
3937 *******************************************************************************/
3939 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
3940 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
3948 /* mark start of dump memory area */
3950 dumpsize = dump_size();
3952 /* get number of Java method arguments */
3954 vmargscount = m->parseddesc->paramcount;
3956 /* allocate vm_arg array */
3958 vmargs = DMNEW(vm_arg, vmargscount);
3960 /* fill the vm_arg array from a va_list */
3962 vm_vmargs_from_valist(m, o, vmargs, ap);
3964 /* call the Java method */
3966 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
3968 /* release dump area */
3970 dump_release(dumpsize);
3975 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o, va_list ap)
3981 /* mark start of dump memory area */
3983 dumpsize = dump_size();
3985 /* fill the argument array from a va_list */
3987 array = vm_array_from_valist(m, o, ap);
3989 /* call the Java method */
3991 f = vm_call_float_array(m, array);
3993 /* release dump area */
3995 dump_release(dumpsize);
4001 /* vm_call_method_float_jvalue *************************************************
4003 Calls a Java method with a variable number of arguments, passed via
4004 a jvalue array, and returns a float.
4006 *******************************************************************************/
4008 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
4009 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
4017 /* mark start of dump memory area */
4019 dumpsize = dump_size();
4021 /* get number of Java method arguments */
4023 vmargscount = m->parseddesc->paramcount;
4025 /* allocate vm_arg array */
4027 vmargs = DMNEW(vm_arg, vmargscount);
4029 /* fill the vm_arg array from a va_list */
4031 vm_vmargs_from_jvalue(m, o, vmargs, args);
4033 /* call the Java method */
4035 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
4037 /* release dump area */
4039 dump_release(dumpsize);
4044 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o, const jvalue *args)
4050 /* mark start of dump memory area */
4052 dumpsize = dump_size();
4054 /* fill the argument array from a va_list */
4056 array = vm_array_from_jvalue(m, o, args);
4058 /* call the Java method */
4060 f = vm_call_float_array(m, array);
4062 /* release dump area */
4064 dump_release(dumpsize);
4071 /* vm_call_double_array ********************************************************
4073 Calls a Java method with a variable number of arguments and returns
4076 *******************************************************************************/
4078 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
4079 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
4084 vm_abort("IMPLEMENT ME!");
4086 STATISTICS(count_calls_native_to_java++);
4088 #if defined(ENABLE_JIT)
4089 # if defined(ENABLE_INTRP)
4091 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4094 d = asm_vm_call_method_double(m, vmargscount, vmargs);
4096 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4102 double vm_call_double_array(methodinfo *m, uint64_t *array)
4109 /* compile the method if not already done */
4111 if (m->code == NULL)
4112 if (!jit_compile(m))
4115 STATISTICS(count_calls_native_to_java++);
4117 #if defined(ENABLE_JIT)
4118 # if defined(ENABLE_INTRP)
4120 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4123 d = asm_vm_call_method_double(m->code->entrypoint, array, md->memuse);
4125 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4133 /* vm_call_method_double *******************************************************
4135 Calls a Java method with a variable number of arguments and returns
4138 *******************************************************************************/
4140 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
4146 d = vm_call_method_double_valist(m, o, ap);
4153 /* vm_call_method_double_valist ************************************************
4155 Calls a Java method with a variable number of arguments, passed via
4156 a va_list, and returns a double.
4158 *******************************************************************************/
4160 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
4161 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
4169 /* mark start of dump memory area */
4171 dumpsize = dump_size();
4173 /* get number of Java method arguments */
4175 vmargscount = m->parseddesc->paramcount;
4177 /* allocate vm_arg array */
4179 vmargs = DMNEW(vm_arg, vmargscount);
4181 /* fill the vm_arg array from a va_list */
4183 vm_vmargs_from_valist(m, o, vmargs, ap);
4185 /* call the Java method */
4187 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
4189 /* release dump area */
4191 dump_release(dumpsize);
4196 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o, va_list ap)
4202 /* mark start of dump memory area */
4204 dumpsize = dump_size();
4206 /* fill the argument array from a va_list */
4208 array = vm_array_from_valist(m, o, ap);
4210 /* call the Java method */
4212 d = vm_call_double_array(m, array);
4214 /* release dump area */
4216 dump_release(dumpsize);
4223 /* vm_call_method_double_jvalue ************************************************
4225 Calls a Java method with a variable number of arguments, passed via
4226 a jvalue array, and returns a double.
4228 *******************************************************************************/
4230 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__) && !defined(__ALPHA__) && !defined(__I386__)
4231 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
4239 /* mark start of dump memory area */
4241 dumpsize = dump_size();
4243 /* get number of Java method arguments */
4245 vmargscount = m->parseddesc->paramcount;
4247 /* allocate vm_arg array */
4249 vmargs = DMNEW(vm_arg, vmargscount);
4251 /* fill the vm_arg array from a va_list */
4253 vm_vmargs_from_jvalue(m, o, vmargs, args);
4255 /* call the Java method */
4257 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
4259 /* release dump area */
4261 dump_release(dumpsize);
4266 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o, const jvalue *args)
4272 /* mark start of dump memory area */
4274 dumpsize = dump_size();
4276 /* fill the argument array from a va_list */
4278 array = vm_array_from_jvalue(m, o, args);
4280 /* call the Java method */
4282 d = vm_call_double_array(m, array);
4284 /* release dump area */
4286 dump_release(dumpsize);
4293 * These are local overrides for various environment variables in Emacs.
4294 * Please do not remove this and leave it at the end of the file, where
4295 * Emacs will automagically detect them.
4296 * ---------------------------------------------------------------------
4299 * indent-tabs-mode: t