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