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