71a94838b7bcdaa0e38f8123b3fe1f0b63edf2d0
[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 linkverbose = false;
79 bool initverbose = false;
80
81 bool opt_verboseclass     = false;
82 bool opt_verbosegc        = false;
83 bool opt_verbosejni       = false;
84 bool opt_verbosecall      = false;      /* trace all method invocation        */
85 bool opt_verbosethreads   = false;
86
87 bool showmethods = false;
88 bool showconstantpool = false;
89 bool showutf = false;
90
91 char *opt_method = NULL;
92 char *opt_signature = NULL;
93
94 bool compileverbose =  false;           /* trace compiler actions             */
95 bool showstack = false;
96
97 bool opt_showdisassemble    = false;    /* generate disassembler listing      */
98 bool opt_shownops           = false;
99 bool opt_showddatasegment   = false;    /* generate data segment listing      */
100 bool opt_showintermediate   = false;    /* generate intermediate code listing */
101
102 bool checkbounds = true;       /* check array bounds                         */
103 bool opt_noieee = false;       /* don't implement ieee compliant floats      */
104 bool checksync = true;         /* do synchronization                         */
105 #if defined(ENABLE_LOOP)
106 bool opt_loops = false;        /* optimize array accesses in loops           */
107 #endif
108
109 bool makeinitializations = true;
110
111 #if defined(ENABLE_STATISTICS)
112 bool opt_stat    = false;
113 bool opt_getloadingtime = false;   /* to measure the runtime                 */
114 bool opt_getcompilingtime = false; /* compute compile time                   */
115 #endif
116 #if defined(ENABLE_VERIFIER)
117 bool opt_verify  = true;       /* true if classfiles should be verified      */
118 #endif
119
120 #if defined(ENABLE_PROFILING)
121 bool opt_prof    = false;
122 bool opt_prof_bb = false;
123 #endif
124
125
126 /* inlining options ***********************************************************/
127
128 #if defined(ENABLE_INLINING)
129 bool opt_inlining = false;
130 #if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
131 s4 opt_inline_debug_min_size = 0;
132 s4 opt_inline_debug_max_size = INT_MAX;
133 s4 opt_inline_debug_end_counter = INT_MAX;
134 bool opt_inline_debug_all = false;
135 #endif /* defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG) */
136 #if !defined(NDEBUG)
137 bool opt_inline_debug_log = false;
138 #endif /* !defined(NDEBUG) */
139 #endif /* defined(ENABLE_INLINING) */
140
141
142 /* optimization options *******************************************************/
143
144 #if defined(ENABLE_IFCONV)
145 bool opt_ifconv = false;
146 #endif
147
148 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
149 bool opt_lsra = false;
150 #endif
151
152
153 /* interpreter options ********************************************************/
154
155 #if defined(ENABLE_INTRP)
156 bool opt_no_dynamic = false;            /* suppress dynamic superinstructions */
157 bool opt_no_replication = false;        /* don't use replication in intrp     */
158 bool opt_no_quicksuper = false;         /* instructions for quickening cannot be
159                                                                                    part of dynamic superinstructions */
160
161 s4   opt_static_supers = 0x7fffffff;
162 bool vm_debug = false;          /* XXX this should be called `opt_trace'      */
163 #endif
164
165 #if defined(ENABLE_DEBUG_FILTER)
166 const char *opt_filter_verbosecall_include = 0;
167 const char *opt_filter_verbosecall_exclude = 0;
168 const char *opt_filter_show_method = 0;
169 #endif
170
171
172 /* -XX options ****************************************************************/
173
174 /* NOTE: For better readability keep these alpha-sorted. */
175
176 int      opt_DebugExceptions           = 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 int32_t  opt_DebugStackTrace           = 0;
183 #if defined(ENABLE_DISASSEMBLER)
184 int      opt_DisassembleStubs          = 0;
185 #endif
186 #if defined(ENABLE_GC_CACAO)
187 int32_t  opt_GCDebugRootSet            = 0;
188 int32_t  opt_GCStress                  = 0;
189 #endif
190 int32_t  opt_MaxPermSize               = 0;
191 int32_t  opt_PermSize                  = 0;
192 int      opt_PrintConfig               = 0;
193 int32_t  opt_ProfileGCMemoryUsage      = 0;
194 int32_t  opt_ProfileMemoryUsage        = 0;
195 FILE    *opt_ProfileMemoryUsageGNUPlot = NULL;
196 int32_t  opt_ThreadStackSize           = 0;
197 int32_t  opt_TraceExceptions           = 0;
198 int32_t  opt_TraceJavaCalls            = 0;
199 int32_t  opt_TraceJNICalls             = 0;
200 int32_t  opt_TraceJVMCalls             = 0;
201 #if defined(ENABLE_REPLACEMENT)
202 int32_t  opt_TraceReplacement          = 0;
203 #endif
204
205
206 enum {
207         OPT_TYPE_BOOLEAN,
208         OPT_TYPE_VALUE
209 };
210
211 enum {
212         OPT_DebugExceptions,
213         OPT_DebugLocks,
214         OPT_DebugPackage,
215         OPT_DebugPatcher,
216         OPT_DebugProperties,
217         OPT_DebugStackFrameInfo,
218         OPT_DebugStackTrace,
219         OPT_DisassembleStubs,
220         OPT_GCDebugRootSet,
221         OPT_GCStress,
222         OPT_MaxPermSize,
223         OPT_PermSize,
224         OPT_PrintConfig,
225         OPT_ProfileGCMemoryUsage,
226         OPT_ProfileMemoryUsage,
227         OPT_ProfileMemoryUsageGNUPlot,
228         OPT_ThreadStackSize,
229         OPT_TraceExceptions,
230         OPT_TraceJavaCalls,
231         OPT_TraceJNICalls,
232         OPT_TraceJVMCalls,
233         OPT_TraceReplacement
234 };
235
236
237 option_t options_XX[] = {
238         { "DebugExceptions",           OPT_DebugExceptions,           OPT_TYPE_BOOLEAN, "debug exceptions" },
239         { "DebugLocks",                OPT_DebugLocks,                OPT_TYPE_BOOLEAN, "print debug information for locks" },
240         { "DebugPackage",              OPT_DebugPackage,              OPT_TYPE_BOOLEAN, "debug Java boot-packages" },
241         { "DebugPatcher",              OPT_DebugPatcher,              OPT_TYPE_BOOLEAN, "debug JIT code patching" },
242         { "DebugProperties",           OPT_DebugProperties,           OPT_TYPE_BOOLEAN, "print debug information for properties" },
243         { "DebugStackFrameInfo",       OPT_DebugStackFrameInfo,       OPT_TYPE_BOOLEAN, "TODO" },
244         { "DebugStackTrace",           OPT_DebugStackTrace,           OPT_TYPE_BOOLEAN, "debug stacktrace creation" },
245 #if defined(ENABLE_DISASSEMBLER)
246         { "DisassembleStubs",          OPT_DisassembleStubs,          OPT_TYPE_BOOLEAN, "disassemble builtin and native stubs when generated" },
247 #endif
248 #if defined(ENABLE_GC_CACAO)
249         { "GCDebugRootSet",            OPT_GCDebugRootSet,            OPT_TYPE_BOOLEAN, "GC: print root-set at collection" },
250         { "GCStress",                  OPT_GCStress,                  OPT_TYPE_BOOLEAN, "GC: forced collection at every allocation" },
251 #endif
252         { "MaxPermSize",               OPT_MaxPermSize,               OPT_TYPE_VALUE,   "not implemented" },
253         { "PermSize",                  OPT_PermSize,                  OPT_TYPE_VALUE,   "not implemented" },
254         { "PrintConfig",               OPT_PrintConfig,               OPT_TYPE_BOOLEAN, "print VM configuration" },
255         { "ProfileGCMemoryUsage",      OPT_ProfileGCMemoryUsage,      OPT_TYPE_VALUE,   "profiles GC memory usage in the given interval, <value> is in seconds (default: 5)" },
256         { "ProfileMemoryUsage",        OPT_ProfileMemoryUsage,        OPT_TYPE_VALUE,   "TODO" },
257         { "ProfileMemoryUsageGNUPlot", OPT_ProfileMemoryUsageGNUPlot, OPT_TYPE_VALUE,   "TODO" },
258         { "ThreadStackSize",           OPT_ThreadStackSize,           OPT_TYPE_VALUE,   "TODO" },
259         { "TraceExceptions",           OPT_TraceExceptions,           OPT_TYPE_BOOLEAN, "trace Exception throwing" },
260         { "TraceJavaCalls",            OPT_TraceJavaCalls,            OPT_TYPE_BOOLEAN, "trace Java method calls" },
261         { "TraceJNICalls",             OPT_TraceJNICalls,             OPT_TYPE_BOOLEAN, "trace JNI method calls" },
262         { "TraceJVMCalls",             OPT_TraceJVMCalls,             OPT_TYPE_BOOLEAN, "TODO" },
263 #if defined(ENABLE_REPLACEMENT)
264         { "TraceReplacement",          OPT_TraceReplacement,          OPT_TYPE_VALUE,   "trace on-stack replacement with the given verbosity level (default: 1)" },
265 #endif
266
267         /* end marker */
268
269         { NULL,                        -1,                            -1, NULL }
270 };
271
272
273 /* options_get *****************************************************************
274
275    DOCUMENT ME!!!
276
277 *******************************************************************************/
278
279 s4 options_get(opt_struct *opts, JavaVMInitArgs *vm_args)
280 {
281         char *option;
282         s4    i;
283
284         if (opt_index >= vm_args->nOptions)
285                 return OPT_DONE;
286
287         /* get the current option */
288
289         option = vm_args->options[opt_index].optionString;
290
291         if ((option == NULL) || (option[0] != '-'))
292                 return OPT_DONE;
293
294         for (i = 0; opts[i].name; i++) {
295                 if (!opts[i].arg) {
296                         /* boolean option found */
297
298                         if (strcmp(option + 1, opts[i].name) == 0) {
299                                 opt_index++;
300                                 return opts[i].value;
301                         }
302
303                 } else {
304                         /* parameter option found */
305
306                         /* with a space between */
307
308                         if (strcmp(option + 1, opts[i].name) == 0) {
309                                 opt_index++;
310
311                                 if (opt_index < vm_args->nOptions) {
312
313 #if defined(HAVE_STRDUP)
314                                         opt_arg = strdup(vm_args->options[opt_index].optionString);
315 #else
316 # error !HAVE_STRDUP
317 #endif
318
319                                         opt_index++;
320                                         return opts[i].value;
321                                 }
322
323                                 return OPT_ERROR;
324
325                         } else {
326                                 /* parameter and option have no space between */
327
328                                 /* FIXME: this assumption is plain wrong, hits you if there is a
329                                  * parameter with no argument starting with same letter as param with argument
330                                  * but named after that one, ouch! */
331
332                                 size_t l = strlen(opts[i].name);
333
334                                 if (strlen(option + 1) > l) {
335                                         if (memcmp(option + 1, opts[i].name, l) == 0) {
336                                                 opt_index++;
337
338 #if defined(HAVE_STRDUP)
339                                                 opt_arg = strdup(option + 1 + l);
340 #else
341 # error !HAVE_STRDUP
342 #endif
343
344                                                 return opts[i].value;
345                                         }
346                                 }
347                         }
348                 }
349         }
350
351         return OPT_ERROR;
352 }
353
354
355 /* options_xxusage *************************************************************
356
357    Print usage message for debugging options.
358
359 *******************************************************************************/
360
361 static void options_xxusage(void)
362 {
363         option_t *opt;
364         int       length;
365         int       i;
366         char     *c;
367
368         for (opt = options_XX; opt->name != NULL; opt++) {
369                 printf("    -XX:");
370
371                 switch (opt->type) {
372                 case OPT_TYPE_BOOLEAN:
373                         printf("+%s", opt->name);
374                         length = strlen("    -XX:+") + strlen(opt->name);
375                         break;
376                 case OPT_TYPE_VALUE:
377                         printf("%s=<value>", opt->name);
378                         length = strlen("    -XX:") + strlen(opt->name) + strlen("=<value>");
379                         break;
380                 }
381
382                 /* Check if the help fits into one 80-column line.
383                    Documentation starts at column 29. */
384
385                 if (length < (29 - 1)) {
386                         /* Print missing spaces up to column 29. */
387
388                         for (i = length; i < 29; i++)
389                                 printf(" ");
390                 }
391                 else {
392                         printf("\n");
393                         printf("                             "); /* 29 spaces */
394                 }
395
396                 /* Check documentation length. */
397
398                 length = strlen(opt->doc);
399
400                 if (length < (80 - 29)) {
401                         printf("%s", opt->doc);
402                 }
403                 else {
404                         for (c = opt->doc, i = 29; *c != 0; c++, i++) {
405                                 /* If we are at the end of the line, break it. */
406
407                                 if (i == 80) {
408                                         printf("\n");
409                                         printf("                             "); /* 29 spaces */
410                                         i = 29;
411                                 }
412
413                                 printf("%c", *c);
414                         }
415                 }
416
417                 printf("\n");
418         }
419
420         /* exit with error code */
421
422         exit(1);
423 }
424
425
426 /* options_xx ******************************************************************
427
428    Handle -XX: options.
429
430 *******************************************************************************/
431
432 void options_xx(JavaVMInitArgs *vm_args)
433 {
434         const char *name;
435         const char *start;
436         char       *end;
437         int         length;
438         int         enable;
439         char       *value;
440         option_t   *opt;
441         char       *filename;
442         FILE       *file;
443         int         i;
444
445         /* Iterate over all passed options. */
446
447         for (i = 0; i < vm_args->nOptions; i++) {
448                 /* Get the current option. */
449
450                 name = vm_args->options[i].optionString;
451
452                 /* Check for help (-XX). */
453
454                 if (strcmp(name, "-XX") == 0)
455                         options_xxusage();
456
457                 /* Check if the option start with -XX. */
458
459                 start = strstr(name, "-XX:");
460
461                 if ((start == NULL) || (start != name))
462                         continue;
463
464                 /* Check if the option is a boolean option. */
465
466                 if (name[4] == '+') {
467                         start  = name + 4 + 1;
468                         enable = 1;
469                 }
470                 else if (name[4] == '-') {
471                         start  = name + 4 + 1;
472                         enable = 0;
473                 }
474                 else {
475                         start  = name + 4;
476                         enable = -1;
477                 }
478
479                 /* Search for a '=' in the option name and get the option name
480                    length and the value of the option. */
481
482                 end = strchr(start, '=');
483
484                 if (end == NULL) {
485                         length = strlen(start);
486                         value  = NULL;
487                 }
488                 else {
489                         length = end - start;
490                         value  = end + 1;
491                 }
492
493                 /* Search the option in the option array. */
494
495                 for (opt = options_XX; opt->name != NULL; opt++) {
496                         if (strncmp(opt->name, start, length) == 0) {
497                                 /* Check if the options passed fits to the type. */
498
499                                 switch (opt->type) {
500                                 case OPT_TYPE_BOOLEAN:
501                                         if ((enable == -1) || (value != NULL))
502                                                 options_xxusage();
503                                         break;
504                                 case OPT_TYPE_VALUE:
505                                         if ((enable != -1) || (value == NULL))
506                                                 options_xxusage();
507                                         break;
508                                 default:
509                                         vm_abort("options_xx: unknown option type %d for option %s",
510                                                          opt->type, opt->name);
511                                 }
512
513                                 break;
514                         }
515                 }
516
517                 /* Process the option. */
518
519                 switch (opt->value) {
520                 case OPT_DebugExceptions:
521                         opt_DebugExceptions = enable;
522                         break;
523
524                 case OPT_DebugLocks:
525                         opt_DebugLocks = enable;
526                         break;
527
528                 case OPT_DebugPackage:
529                         opt_DebugPackage = enable;
530                         break;
531
532                 case OPT_DebugPatcher:
533                         opt_DebugPatcher = enable;
534                         break;
535
536                 case OPT_DebugProperties:
537                         opt_DebugProperties = enable;
538                         break;
539
540                 case OPT_DebugStackFrameInfo:
541                         opt_DebugStackFrameInfo = enable;
542                         break;
543
544
545 #if defined(ENABLE_DISASSEMBLER)
546         case OPT_DisassembleStubs:
547                 opt_DisassembleStubs = enable;
548                 break;
549 #endif
550
551 #if defined(ENABLE_GC_CACAO)
552                 case OPT_GCDebugRootSet:
553                         opt_GCDebugRootSet = enable;
554                         break;
555
556                 case OPT_GCStress:
557                         opt_GCStress = enable;
558                         break;
559 #endif
560
561                 case OPT_MaxPermSize:
562                         /* currently ignored */
563                         break;
564
565                 case OPT_PermSize:
566                         /* currently ignored */
567                         break;
568
569                 case OPT_PrintConfig:
570                         vm_printconfig();
571                         break;
572
573                 case OPT_ProfileGCMemoryUsage:
574                         if (value == NULL)
575                                 opt_ProfileGCMemoryUsage = 5;
576                         else
577                                 opt_ProfileGCMemoryUsage = atoi(value);
578                         break;
579
580                 case OPT_ProfileMemoryUsage:
581                         if (value == NULL)
582                                 opt_ProfileMemoryUsage = 5;
583                         else
584                                 opt_ProfileMemoryUsage = atoi(value);
585
586 # if defined(ENABLE_STATISTICS)
587                         /* we also need statistics */
588
589                         opt_stat = true;
590 # endif
591                         break;
592
593                 case OPT_ProfileMemoryUsageGNUPlot:
594                         if (value == NULL)
595                                 filename = "profile.dat";
596                         else
597                                 filename = value;
598
599                         file = fopen(filename, "w");
600
601                         if (file == NULL)
602                                 vm_abort("options_xx: fopen failed: %s", strerror(errno));
603
604                         opt_ProfileMemoryUsageGNUPlot = file;
605                         break;
606
607                 case OPT_ThreadStackSize:
608                         /* currently ignored */
609                         break;
610
611                 case OPT_TraceExceptions:
612                         opt_TraceExceptions = enable;
613                         break;
614
615                 case OPT_TraceJavaCalls:
616                         opt_verbosecall = enable;
617                         opt_TraceJavaCalls = enable;
618                         break;
619
620                 case OPT_TraceJNICalls:
621                         opt_TraceJNICalls = enable;
622                         break;
623
624                 case OPT_TraceJVMCalls:
625                         opt_TraceJVMCalls = enable;
626                         break;
627
628 #if defined(ENABLE_REPLACEMENT)
629                 case OPT_TraceReplacement:
630                         if (value == NULL)
631                                 opt_TraceReplacement = 1;
632                         else
633                                 opt_TraceReplacement = atoi(value);
634                         break;
635 #endif
636
637                 default:
638                         printf("Unknown -XX option: %s\n", name);
639                         break;
640                 }
641         }
642 }
643
644
645 /*
646  * These are local overrides for various environment variables in Emacs.
647  * Please do not remove this and leave it at the end of the file, where
648  * Emacs will automagically detect them.
649  * ---------------------------------------------------------------------
650  * Local variables:
651  * mode: c
652  * indent-tabs-mode: t
653  * c-basic-offset: 4
654  * tab-width: 4
655  * End:
656  */