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