* src/vm/finalizer.c (finalizer_run): Fixed for handles and added boehm-hack.
[cacao.git] / src / vmcore / options.c
1 /* src/vmcore/options.c - contains global options
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25 */
26
27
28 #include "config.h"
29
30 #include <errno.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34
35 #if defined(HAVE_STRING_H)
36 # include <string.h>
37 #endif
38
39 #include <limits.h>
40
41 #include "mm/memory.h"
42
43 #include "native/jni.h"
44
45 #include "vm/vm.h"
46
47 #include "vmcore/options.h"
48
49
50 /* command line option ********************************************************/
51
52 s4    opt_index = 0;            /* index of processed arguments               */
53 char *opt_arg;                  /* this one exports the option argument       */
54
55 bool opt_foo = false;           /* option for development                     */
56
57 bool opt_jar = false;
58
59 #if defined(ENABLE_JIT)
60 bool opt_jit = true;            /* JIT mode execution (default)               */
61 bool opt_intrp = false;         /* interpreter mode execution                 */
62 #else
63 bool opt_jit = false;           /* JIT mode execution                         */
64 bool opt_intrp = true;          /* interpreter mode execution (default)       */
65 #endif
66
67 bool opt_run = true;
68
69 s4   opt_heapmaxsize   = 0;     /* maximum heap size                          */
70 s4   opt_heapstartsize = 0;     /* initial heap size                          */
71 s4   opt_stacksize     = 0;     /* thread stack size                          */
72
73 bool opt_verbose = false;
74 bool opt_debugcolor = false;    /* use ANSI terminal sequences                */
75 bool compileall = false;
76
77 bool loadverbose = false;
78 bool initverbose = false;
79
80 bool opt_verboseclass     = false;
81 bool opt_verbosegc        = false;
82 bool opt_verbosejni       = false;
83 bool opt_verbosecall      = false;      /* trace all method invocation        */
84
85 bool showmethods = false;
86 bool showconstantpool = false;
87 bool showutf = false;
88
89 char *opt_method = NULL;
90 char *opt_signature = NULL;
91
92 bool compileverbose =  false;           /* trace compiler actions             */
93 bool showstack = false;
94
95 bool opt_showdisassemble    = false;    /* generate disassembler listing      */
96 bool opt_shownops           = false;
97 bool opt_showddatasegment   = false;    /* generate data segment listing      */
98 bool opt_showintermediate   = false;    /* generate intermediate code listing */
99
100 bool checkbounds = true;       /* check array bounds                         */
101 bool opt_noieee = false;       /* don't implement ieee compliant floats      */
102 bool checksync = true;         /* do synchronization                         */
103 #if defined(ENABLE_LOOP)
104 bool opt_loops = false;        /* optimize array accesses in loops           */
105 #endif
106
107 bool makeinitializations = true;
108
109 #if defined(ENABLE_STATISTICS)
110 bool opt_stat    = false;
111 bool opt_getloadingtime = false;   /* to measure the runtime                 */
112 bool opt_getcompilingtime = false; /* compute compile time                   */
113 #endif
114 #if defined(ENABLE_VERIFIER)
115 bool opt_verify  = true;       /* true if classfiles should be verified      */
116 #endif
117
118 #if defined(ENABLE_PROFILING)
119 bool opt_prof    = false;
120 bool opt_prof_bb = false;
121 #endif
122
123
124 /* inlining options ***********************************************************/
125
126 #if defined(ENABLE_INLINING)
127 bool opt_inlining = false;
128 #if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
129 s4 opt_inline_debug_min_size = 0;
130 s4 opt_inline_debug_max_size = INT_MAX;
131 s4 opt_inline_debug_end_counter = INT_MAX;
132 bool opt_inline_debug_all = false;
133 #endif /* defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG) */
134 #if !defined(NDEBUG)
135 bool opt_inline_debug_log = false;
136 #endif /* !defined(NDEBUG) */
137 #endif /* defined(ENABLE_INLINING) */
138
139
140 /* optimization options *******************************************************/
141
142 #if defined(ENABLE_IFCONV)
143 bool opt_ifconv = false;
144 #endif
145
146 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
147 bool opt_lsra = false;
148 #endif
149
150
151 /* interpreter options ********************************************************/
152
153 #if defined(ENABLE_INTRP)
154 bool opt_no_dynamic = false;            /* suppress dynamic superinstructions */
155 bool opt_no_replication = false;        /* don't use replication in intrp     */
156 bool opt_no_quicksuper = false;         /* instructions for quickening cannot be
157                                                                                    part of dynamic superinstructions */
158
159 s4   opt_static_supers = 0x7fffffff;
160 bool vm_debug = false;          /* XXX this should be called `opt_trace'      */
161 #endif
162
163 #if defined(ENABLE_DEBUG_FILTER)
164 const char *opt_filter_verbosecall_include = 0;
165 const char *opt_filter_verbosecall_exclude = 0;
166 const char *opt_filter_show_method = 0;
167 #endif
168
169
170 /* -XX options ****************************************************************/
171
172 /* NOTE: For better readability keep these alpha-sorted. */
173
174 int      opt_DebugExceptions           = 0;
175 int      opt_DebugFinalizer            = 0;
176 int      opt_DebugLocalReferences      = 0;
177 int      opt_DebugLocks                = 0;
178 int      opt_DebugPackage              = 0;
179 int      opt_DebugPatcher              = 0;
180 int      opt_DebugProperties           = 0;
181 int32_t  opt_DebugStackFrameInfo       = 0;
182 int      opt_DebugStackTrace           = 0;
183 int      opt_DebugThreads              = 0;
184 #if defined(ENABLE_DISASSEMBLER)
185 int      opt_DisassembleStubs          = 0;
186 #endif
187 #if defined(ENABLE_GC_CACAO)
188 int32_t  opt_GCDebugRootSet            = 0;
189 int32_t  opt_GCStress                  = 0;
190 #endif
191 int32_t  opt_MaxPermSize               = 0;
192 int32_t  opt_PermSize                  = 0;
193 int      opt_PrintConfig               = 0;
194 int32_t  opt_ProfileGCMemoryUsage      = 0;
195 int32_t  opt_ProfileMemoryUsage        = 0;
196 FILE    *opt_ProfileMemoryUsageGNUPlot = NULL;
197 #if defined(ENABLE_REPLACEMENT)
198 int      opt_TestReplacement           = 0;
199 #endif
200 int32_t  opt_ThreadStackSize           = 0;
201 int      opt_TraceCompilerCalls        = 0;
202 int32_t  opt_TraceExceptions           = 0;
203 int32_t  opt_TraceJavaCalls            = 0;
204 int32_t  opt_TraceJNICalls             = 0;
205 int32_t  opt_TraceJVMCalls             = 0;
206 int32_t  opt_TraceLinkClass            = 0;
207 #if defined(ENABLE_REPLACEMENT)
208 int32_t  opt_TraceReplacement          = 0;
209 #endif
210
211
212 enum {
213         OPT_TYPE_BOOLEAN,
214         OPT_TYPE_VALUE
215 };
216
217 enum {
218         OPT_DebugExceptions,
219         OPT_DebugFinalizer,
220         OPT_DebugLocalReferences,
221         OPT_DebugLocks,
222         OPT_DebugPackage,
223         OPT_DebugPatcher,
224         OPT_DebugProperties,
225         OPT_DebugStackFrameInfo,
226         OPT_DebugStackTrace,
227         OPT_DebugThreads,
228         OPT_DisassembleStubs,
229         OPT_GCDebugRootSet,
230         OPT_GCStress,
231         OPT_MaxPermSize,
232         OPT_PermSize,
233         OPT_PrintConfig,
234         OPT_ProfileGCMemoryUsage,
235         OPT_ProfileMemoryUsage,
236         OPT_ProfileMemoryUsageGNUPlot,
237         OPT_TestReplacement,
238         OPT_ThreadStackSize,
239         OPT_TraceCompilerCalls,
240         OPT_TraceExceptions,
241         OPT_TraceJavaCalls,
242         OPT_TraceJNICalls,
243         OPT_TraceJVMCalls,
244         OPT_TraceLinkClass,
245         OPT_TraceReplacement
246 };
247
248
249 option_t options_XX[] = {
250         { "DebugExceptions",           OPT_DebugExceptions,           OPT_TYPE_BOOLEAN, "debug exceptions" },
251         { "DebugFinalizer",            OPT_DebugFinalizer,            OPT_TYPE_BOOLEAN, "debug finalizer thread" },
252         { "DebugLocalReferences",      OPT_DebugLocalReferences,      OPT_TYPE_BOOLEAN, "print debug information for local reference tables" },
253         { "DebugLocks",                OPT_DebugLocks,                OPT_TYPE_BOOLEAN, "print debug information for locks" },
254         { "DebugPackage",              OPT_DebugPackage,              OPT_TYPE_BOOLEAN, "debug Java boot-packages" },
255         { "DebugPatcher",              OPT_DebugPatcher,              OPT_TYPE_BOOLEAN, "debug JIT code patching" },
256         { "DebugProperties",           OPT_DebugProperties,           OPT_TYPE_BOOLEAN, "print debug information for properties" },
257         { "DebugStackFrameInfo",       OPT_DebugStackFrameInfo,       OPT_TYPE_BOOLEAN, "TODO" },
258         { "DebugStackTrace",           OPT_DebugStackTrace,           OPT_TYPE_BOOLEAN, "debug stacktrace creation" },
259         { "DebugThreads",              OPT_DebugThreads,              OPT_TYPE_BOOLEAN, "print debug information for threads" },
260 #if defined(ENABLE_DISASSEMBLER)
261         { "DisassembleStubs",          OPT_DisassembleStubs,          OPT_TYPE_BOOLEAN, "disassemble builtin and native stubs when generated" },
262 #endif
263 #if defined(ENABLE_GC_CACAO)
264         { "GCDebugRootSet",            OPT_GCDebugRootSet,            OPT_TYPE_BOOLEAN, "GC: print root-set at collection" },
265         { "GCStress",                  OPT_GCStress,                  OPT_TYPE_BOOLEAN, "GC: forced collection at every allocation" },
266 #endif
267         { "MaxPermSize",               OPT_MaxPermSize,               OPT_TYPE_VALUE,   "not implemented" },
268         { "PermSize",                  OPT_PermSize,                  OPT_TYPE_VALUE,   "not implemented" },
269         { "PrintConfig",               OPT_PrintConfig,               OPT_TYPE_BOOLEAN, "print VM configuration" },
270         { "ProfileGCMemoryUsage",      OPT_ProfileGCMemoryUsage,      OPT_TYPE_VALUE,   "profiles GC memory usage in the given interval, <value> is in seconds (default: 5)" },
271         { "ProfileMemoryUsage",        OPT_ProfileMemoryUsage,        OPT_TYPE_VALUE,   "TODO" },
272         { "ProfileMemoryUsageGNUPlot", OPT_ProfileMemoryUsageGNUPlot, OPT_TYPE_VALUE,   "TODO" },
273 #if defined(ENABLE_REPLACEMENT)
274         { "TestReplacement"          , OPT_TestReplacement,           OPT_TYPE_BOOLEAN, "activate all replacement points during code generation" },
275 #endif
276         { "ThreadStackSize",           OPT_ThreadStackSize,           OPT_TYPE_VALUE,   "TODO" },
277         { "TraceCompilerCalls",        OPT_TraceCompilerCalls,        OPT_TYPE_BOOLEAN, "trace JIT compiler calls" },
278         { "TraceExceptions",           OPT_TraceExceptions,           OPT_TYPE_BOOLEAN, "trace Exception throwing" },
279         { "TraceJavaCalls",            OPT_TraceJavaCalls,            OPT_TYPE_BOOLEAN, "trace Java method calls" },
280         { "TraceJNICalls",             OPT_TraceJNICalls,             OPT_TYPE_BOOLEAN, "trace JNI method calls" },
281         { "TraceJVMCalls",             OPT_TraceJVMCalls,             OPT_TYPE_BOOLEAN, "TODO" },
282         { "TraceLinkClass",            OPT_TraceLinkClass,            OPT_TYPE_BOOLEAN, "trace class linking" },
283 #if defined(ENABLE_REPLACEMENT)
284         { "TraceReplacement",          OPT_TraceReplacement,          OPT_TYPE_VALUE,   "trace on-stack replacement with the given verbosity level (default: 1)" },
285 #endif
286
287         /* end marker */
288
289         { NULL,                        -1,                            -1, NULL }
290 };
291
292
293 /* options_get *****************************************************************
294
295    DOCUMENT ME!!!
296
297 *******************************************************************************/
298
299 s4 options_get(opt_struct *opts, JavaVMInitArgs *vm_args)
300 {
301         char *option;
302         s4    i;
303
304         if (opt_index >= vm_args->nOptions)
305                 return OPT_DONE;
306
307         /* get the current option */
308
309         option = vm_args->options[opt_index].optionString;
310
311         if ((option == NULL) || (option[0] != '-'))
312                 return OPT_DONE;
313
314         for (i = 0; opts[i].name; i++) {
315                 if (!opts[i].arg) {
316                         /* boolean option found */
317
318                         if (strcmp(option + 1, opts[i].name) == 0) {
319                                 opt_index++;
320                                 return opts[i].value;
321                         }
322
323                 } else {
324                         /* parameter option found */
325
326                         /* with a space between */
327
328                         if (strcmp(option + 1, opts[i].name) == 0) {
329                                 opt_index++;
330
331                                 if (opt_index < vm_args->nOptions) {
332
333 #if defined(HAVE_STRDUP)
334                                         opt_arg = strdup(vm_args->options[opt_index].optionString);
335 #else
336 # error !HAVE_STRDUP
337 #endif
338
339                                         opt_index++;
340                                         return opts[i].value;
341                                 }
342
343                                 return OPT_ERROR;
344
345                         } else {
346                                 /* parameter and option have no space between */
347
348                                 /* FIXME: this assumption is plain wrong, hits you if there is a
349                                  * parameter with no argument starting with same letter as param with argument
350                                  * but named after that one, ouch! */
351
352                                 size_t l = strlen(opts[i].name);
353
354                                 if (strlen(option + 1) > l) {
355                                         if (memcmp(option + 1, opts[i].name, l) == 0) {
356                                                 opt_index++;
357
358 #if defined(HAVE_STRDUP)
359                                                 opt_arg = strdup(option + 1 + l);
360 #else
361 # error !HAVE_STRDUP
362 #endif
363
364                                                 return opts[i].value;
365                                         }
366                                 }
367                         }
368                 }
369         }
370
371         return OPT_ERROR;
372 }
373
374
375 /* options_xxusage *************************************************************
376
377    Print usage message for debugging options.
378
379 *******************************************************************************/
380
381 static void options_xxusage(void)
382 {
383         option_t *opt;
384         int       length;
385         int       i;
386         char     *c;
387
388         for (opt = options_XX; opt->name != NULL; opt++) {
389                 printf("    -XX:");
390
391                 switch (opt->type) {
392                 case OPT_TYPE_BOOLEAN:
393                         printf("+%s", opt->name);
394                         length = strlen("    -XX:+") + strlen(opt->name);
395                         break;
396                 case OPT_TYPE_VALUE:
397                         printf("%s=<value>", opt->name);
398                         length = strlen("    -XX:") + strlen(opt->name) + strlen("=<value>");
399                         break;
400                 }
401
402                 /* Check if the help fits into one 80-column line.
403                    Documentation starts at column 29. */
404
405                 if (length < (29 - 1)) {
406                         /* Print missing spaces up to column 29. */
407
408                         for (i = length; i < 29; i++)
409                                 printf(" ");
410                 }
411                 else {
412                         printf("\n");
413                         printf("                             "); /* 29 spaces */
414                 }
415
416                 /* Check documentation length. */
417
418                 length = strlen(opt->doc);
419
420                 if (length < (80 - 29)) {
421                         printf("%s", opt->doc);
422                 }
423                 else {
424                         for (c = opt->doc, i = 29; *c != 0; c++, i++) {
425                                 /* If we are at the end of the line, break it. */
426
427                                 if (i == 80) {
428                                         printf("\n");
429                                         printf("                             "); /* 29 spaces */
430                                         i = 29;
431                                 }
432
433                                 printf("%c", *c);
434                         }
435                 }
436
437                 printf("\n");
438         }
439
440         /* exit with error code */
441
442         exit(1);
443 }
444
445
446 /* options_xx ******************************************************************
447
448    Handle -XX: options.
449
450 *******************************************************************************/
451
452 void options_xx(JavaVMInitArgs *vm_args)
453 {
454         const char *name;
455         const char *start;
456         char       *end;
457         int         length;
458         int         enable;
459         char       *value;
460         option_t   *opt;
461         char       *filename;
462         FILE       *file;
463         int         i;
464
465         /* Iterate over all passed options. */
466
467         for (i = 0; i < vm_args->nOptions; i++) {
468                 /* Get the current option. */
469
470                 name = vm_args->options[i].optionString;
471
472                 /* Check for help (-XX). */
473
474                 if (strcmp(name, "-XX") == 0)
475                         options_xxusage();
476
477                 /* Check if the option start with -XX. */
478
479                 start = strstr(name, "-XX:");
480
481                 if ((start == NULL) || (start != name))
482                         continue;
483
484                 /* Check if the option is a boolean option. */
485
486                 if (name[4] == '+') {
487                         start  = name + 4 + 1;
488                         enable = 1;
489                 }
490                 else if (name[4] == '-') {
491                         start  = name + 4 + 1;
492                         enable = 0;
493                 }
494                 else {
495                         start  = name + 4;
496                         enable = -1;
497                 }
498
499                 /* Search for a '=' in the option name and get the option name
500                    length and the value of the option. */
501
502                 end = strchr(start, '=');
503
504                 if (end == NULL) {
505                         length = strlen(start);
506                         value  = NULL;
507                 }
508                 else {
509                         length = end - start;
510                         value  = end + 1;
511                 }
512
513                 /* Search the option in the option array. */
514
515                 for (opt = options_XX; opt->name != NULL; opt++) {
516                         if (strncmp(opt->name, start, length) == 0) {
517                                 /* Check if the options passed fits to the type. */
518
519                                 switch (opt->type) {
520                                 case OPT_TYPE_BOOLEAN:
521                                         if ((enable == -1) || (value != NULL))
522                                                 options_xxusage();
523                                         break;
524                                 case OPT_TYPE_VALUE:
525                                         if ((enable != -1) || (value == NULL))
526                                                 options_xxusage();
527                                         break;
528                                 default:
529                                         vm_abort("options_xx: unknown option type %d for option %s",
530                                                          opt->type, opt->name);
531                                 }
532
533                                 break;
534                         }
535                 }
536
537                 /* Process the option. */
538
539                 switch (opt->value) {
540                 case OPT_DebugExceptions:
541                         opt_DebugExceptions = enable;
542                         break;
543
544                 case OPT_DebugFinalizer:
545                         opt_DebugFinalizer = enable;
546                         break;
547
548                 case OPT_DebugLocalReferences:
549                         opt_DebugLocalReferences = enable;
550                         break;
551
552                 case OPT_DebugLocks:
553                         opt_DebugLocks = enable;
554                         break;
555
556                 case OPT_DebugPackage:
557                         opt_DebugPackage = enable;
558                         break;
559
560                 case OPT_DebugPatcher:
561                         opt_DebugPatcher = enable;
562                         break;
563
564                 case OPT_DebugProperties:
565                         opt_DebugProperties = enable;
566                         break;
567
568                 case OPT_DebugStackFrameInfo:
569                         opt_DebugStackFrameInfo = enable;
570                         break;
571
572                 case OPT_DebugStackTrace:
573                         opt_DebugStackTrace = enable;
574                         break;
575
576                 case OPT_DebugThreads:
577                         opt_DebugThreads = enable;
578                         break;
579
580 #if defined(ENABLE_DISASSEMBLER)
581                 case OPT_DisassembleStubs:
582                         opt_DisassembleStubs = enable;
583                         break;
584 #endif
585
586 #if defined(ENABLE_GC_CACAO)
587                 case OPT_GCDebugRootSet:
588                         opt_GCDebugRootSet = enable;
589                         break;
590
591                 case OPT_GCStress:
592                         opt_GCStress = enable;
593                         break;
594 #endif
595
596                 case OPT_MaxPermSize:
597                         /* currently ignored */
598                         break;
599
600                 case OPT_PermSize:
601                         /* currently ignored */
602                         break;
603
604                 case OPT_PrintConfig:
605                         opt_PrintConfig = enable;
606                         break;
607
608                 case OPT_ProfileGCMemoryUsage:
609                         if (value == NULL)
610                                 opt_ProfileGCMemoryUsage = 5;
611                         else
612                                 opt_ProfileGCMemoryUsage = atoi(value);
613                         break;
614
615                 case OPT_ProfileMemoryUsage:
616                         if (value == NULL)
617                                 opt_ProfileMemoryUsage = 5;
618                         else
619                                 opt_ProfileMemoryUsage = atoi(value);
620
621 # if defined(ENABLE_STATISTICS)
622                         /* we also need statistics */
623
624                         opt_stat = true;
625 # endif
626                         break;
627
628                 case OPT_ProfileMemoryUsageGNUPlot:
629                         if (value == NULL)
630                                 filename = "profile.dat";
631                         else
632                                 filename = value;
633
634                         file = fopen(filename, "w");
635
636                         if (file == NULL)
637                                 vm_abort("options_xx: fopen failed: %s", strerror(errno));
638
639                         opt_ProfileMemoryUsageGNUPlot = file;
640                         break;
641
642 #if defined(ENABLE_REPLACEMENT)
643                 case OPT_TestReplacement:
644                         opt_TestReplacement = enable;
645                         break;
646 #endif
647
648                 case OPT_ThreadStackSize:
649                         /* currently ignored */
650                         break;
651
652                 case OPT_TraceCompilerCalls:
653                         opt_TraceCompilerCalls = enable;
654                         break;
655
656                 case OPT_TraceExceptions:
657                         opt_TraceExceptions = enable;
658                         break;
659
660                 case OPT_TraceJavaCalls:
661                         opt_verbosecall = enable;
662                         opt_TraceJavaCalls = enable;
663                         break;
664
665                 case OPT_TraceJNICalls:
666                         opt_TraceJNICalls = enable;
667                         break;
668
669                 case OPT_TraceJVMCalls:
670                         opt_TraceJVMCalls = enable;
671                         break;
672
673                 case OPT_TraceLinkClass:
674                         opt_TraceLinkClass = enable;
675                         break;
676
677 #if defined(ENABLE_REPLACEMENT)
678                 case OPT_TraceReplacement:
679                         if (value == NULL)
680                                 opt_TraceReplacement = 1;
681                         else
682                                 opt_TraceReplacement = atoi(value);
683                         break;
684 #endif
685
686                 default:
687                         printf("Unknown -XX option: %s\n", name);
688                         break;
689                 }
690         }
691 }
692
693
694 /*
695  * These are local overrides for various environment variables in Emacs.
696  * Please do not remove this and leave it at the end of the file, where
697  * Emacs will automagically detect them.
698  * ---------------------------------------------------------------------
699  * Local variables:
700  * mode: c
701  * indent-tabs-mode: t
702  * c-basic-offset: 4
703  * tab-width: 4
704  * End:
705  */