commandLineFlagRangeList.cpp revision 8569:5bbf25472731
1/*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "classfile/stringTable.hpp"
27#include "classfile/symbolTable.hpp"
28#include "gc/shared/referenceProcessor.hpp"
29#include "runtime/arguments.hpp"
30#include "runtime/commandLineFlagRangeList.hpp"
31#include "runtime/os.hpp"
32#include "utilities/defaultStream.hpp"
33#include "utilities/macros.hpp"
34
35class CommandLineFlagRange_int : public CommandLineFlagRange {
36  int _min;
37  int _max;
38
39public:
40  // the "name" argument must be a string literal
41  CommandLineFlagRange_int(const char* name, int min, int max) : CommandLineFlagRange(name) {
42    _min=min, _max=max;
43  }
44
45  Flag::Error check_int(int value, bool verbose = true) {
46    if ((value < _min) || (value > _max)) {
47      if (verbose == true) {
48        jio_fprintf(defaultStream::error_stream(),
49                    "int %s=%d is outside the allowed range [ %d ... %d ]\n",
50                    name(), value, _min, _max);
51      }
52      return Flag::OUT_OF_BOUNDS;
53    } else {
54      return Flag::SUCCESS;
55    }
56  }
57
58  void print(outputStream* st) {
59    st->print("[ %-25d ... %25d ]", _min, _max);
60  }
61};
62
63class CommandLineFlagRange_intx : public CommandLineFlagRange {
64  intx _min;
65  intx _max;
66
67public:
68  // the "name" argument must be a string literal
69  CommandLineFlagRange_intx(const char* name, intx min, intx max) : CommandLineFlagRange(name) {
70    _min=min, _max=max;
71  }
72
73  Flag::Error check_intx(intx value, bool verbose = true) {
74    if ((value < _min) || (value > _max)) {
75      if (verbose == true) {
76        jio_fprintf(defaultStream::error_stream(),
77                    "intx %s=" INTX_FORMAT " is outside the allowed range [ " INTX_FORMAT " ... " INTX_FORMAT " ]\n",
78                    name(), value, _min, _max);
79      }
80      return Flag::OUT_OF_BOUNDS;
81    } else {
82      return Flag::SUCCESS;
83    }
84  }
85
86  void print(outputStream* st) {
87    st->print("[ "INTX_FORMAT_W(-25)" ... "INTX_FORMAT_W(25)" ]", _min, _max);
88  }
89};
90
91class CommandLineFlagRange_uint : public CommandLineFlagRange {
92  uint _min;
93  uint _max;
94
95public:
96  // the "name" argument must be a string literal
97  CommandLineFlagRange_uint(const char* name, uint min, uint max) : CommandLineFlagRange(name) {
98    _min=min, _max=max;
99  }
100
101  Flag::Error check_uint(uint value, bool verbose = true) {
102    if ((value < _min) || (value > _max)) {
103      if (verbose == true) {
104        jio_fprintf(defaultStream::error_stream(),
105                    "uintx %s=%u is outside the allowed range [ %u ... %u ]\n",
106                    name(), value, _min, _max);
107      }
108      return Flag::OUT_OF_BOUNDS;
109    } else {
110      return Flag::SUCCESS;
111    }
112  }
113
114  void print(outputStream* st) {
115    st->print("[ %-25u ... %25u ]", _min, _max);
116  }
117};
118
119class CommandLineFlagRange_uintx : public CommandLineFlagRange {
120  uintx _min;
121  uintx _max;
122
123public:
124  // the "name" argument must be a string literal
125  CommandLineFlagRange_uintx(const char* name, uintx min, uintx max) : CommandLineFlagRange(name) {
126    _min=min, _max=max;
127  }
128
129  Flag::Error check_uintx(uintx value, bool verbose = true) {
130    if ((value < _min) || (value > _max)) {
131      if (verbose == true) {
132        jio_fprintf(defaultStream::error_stream(),
133                    "uintx %s=" UINTX_FORMAT " is outside the allowed range [ " UINTX_FORMAT " ... " UINTX_FORMAT " ]\n",
134                    name(), value, _min, _max);
135      }
136      return Flag::OUT_OF_BOUNDS;
137    } else {
138      return Flag::SUCCESS;
139    }
140  }
141
142  void print(outputStream* st) {
143    st->print("[ "UINTX_FORMAT_W(-25)" ... "UINTX_FORMAT_W(25)" ]", _min, _max);
144  }
145};
146
147class CommandLineFlagRange_uint64_t : public CommandLineFlagRange {
148  uint64_t _min;
149  uint64_t _max;
150
151public:
152  // the "name" argument must be a string literal
153  CommandLineFlagRange_uint64_t(const char* name, uint64_t min, uint64_t max) : CommandLineFlagRange(name) {
154    _min=min, _max=max;
155  }
156
157  Flag::Error check_uint64_t(uint64_t value, bool verbose = true) {
158    if ((value < _min) || (value > _max)) {
159      if (verbose == true) {
160        jio_fprintf(defaultStream::error_stream(),
161                    "uint64_t %s=" UINT64_FORMAT " is outside the allowed range [ " UINT64_FORMAT " ... " UINT64_FORMAT " ]\n",
162                    name(), value, _min, _max);
163      }
164      return Flag::OUT_OF_BOUNDS;
165    } else {
166      return Flag::SUCCESS;
167    }
168  }
169
170  void print(outputStream* st) {
171    st->print("[ "UINT64_FORMAT_W(-25)" ... "UINT64_FORMAT_W(25)" ]", _min, _max);
172  }
173};
174
175class CommandLineFlagRange_size_t : public CommandLineFlagRange {
176  size_t _min;
177  size_t _max;
178
179public:
180  // the "name" argument must be a string literal
181  CommandLineFlagRange_size_t(const char* name, size_t min, size_t max) : CommandLineFlagRange(name) {
182    _min=min, _max=max;
183  }
184
185  Flag::Error check_size_t(size_t value, bool verbose = true) {
186    if ((value < _min) || (value > _max)) {
187      if (verbose == true) {
188        jio_fprintf(defaultStream::error_stream(),
189                    "size_t %s=" SIZE_FORMAT " is outside the allowed range [ " SIZE_FORMAT " ... " SIZE_FORMAT " ]\n",
190                    name(), value, _min, _max);
191      }
192      return Flag::OUT_OF_BOUNDS;
193    } else {
194      return Flag::SUCCESS;
195    }
196  }
197
198  void print(outputStream* st) {
199    st->print("[ "SIZE_FORMAT_W(-25)" ... "SIZE_FORMAT_W(25)" ]", _min, _max);
200  }
201};
202
203class CommandLineFlagRange_double : public CommandLineFlagRange {
204  double _min;
205  double _max;
206
207public:
208  // the "name" argument must be a string literal
209  CommandLineFlagRange_double(const char* name, double min, double max) : CommandLineFlagRange(name) {
210    _min=min, _max=max;
211  }
212
213  Flag::Error check_double(double value, bool verbose = true) {
214    if ((value < _min) || (value > _max)) {
215      if (verbose == true) {
216        jio_fprintf(defaultStream::error_stream(),
217                    "double %s=%f is outside the allowed range [ %f ... %f ]\n",
218                    name(), value, _min, _max);
219      }
220      return Flag::OUT_OF_BOUNDS;
221    } else {
222      return Flag::SUCCESS;
223    }
224  }
225
226  void print(outputStream* st) {
227    st->print("[ %-25.3f ... %25.3f ]", _min, _max);
228  }
229};
230
231// No constraint emitting
232void emit_range_no(...)                         { /* NOP */ }
233
234// No constraint emitting if function argument is NOT provided
235void emit_range_bool(const char* /*name*/)      { /* NOP */ }
236void emit_range_ccstr(const char* /*name*/)     { /* NOP */ }
237void emit_range_ccstrlist(const char* /*name*/) { /* NOP */ }
238void emit_range_int(const char* /*name*/)       { /* NOP */ }
239void emit_range_intx(const char* /*name*/)      { /* NOP */ }
240void emit_range_uint(const char* /*name*/)      { /* NOP */ }
241void emit_range_uintx(const char* /*name*/)     { /* NOP */ }
242void emit_range_uint64_t(const char* /*name*/)  { /* NOP */ }
243void emit_range_size_t(const char* /*name*/)    { /* NOP */ }
244void emit_range_double(const char* /*name*/)    { /* NOP */ }
245
246// CommandLineFlagRange emitting code functions if range arguments are provided
247void emit_range_intx(const char* name, intx min, intx max) {
248  CommandLineFlagRangeList::add(new CommandLineFlagRange_intx(name, min, max));
249}
250void emit_range_uintx(const char* name, uintx min, uintx max) {
251  CommandLineFlagRangeList::add(new CommandLineFlagRange_uintx(name, min, max));
252}
253void emit_range_uint64_t(const char* name, uint64_t min, uint64_t max) {
254  CommandLineFlagRangeList::add(new CommandLineFlagRange_uint64_t(name, min, max));
255}
256void emit_range_size_t(const char* name, size_t min, size_t max) {
257  CommandLineFlagRangeList::add(new CommandLineFlagRange_size_t(name, min, max));
258}
259void emit_range_double(const char* name, double min, double max) {
260  CommandLineFlagRangeList::add(new CommandLineFlagRange_double(name, min, max));
261}
262
263// Generate code to call emit_range_xxx function
264#define EMIT_RANGE_PRODUCT_FLAG(type, name, value, doc)      ); emit_range_##type(#name
265#define EMIT_RANGE_COMMERCIAL_FLAG(type, name, value, doc)   ); emit_range_##type(#name
266#define EMIT_RANGE_DIAGNOSTIC_FLAG(type, name, value, doc)   ); emit_range_##type(#name
267#define EMIT_RANGE_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_range_##type(#name
268#define EMIT_RANGE_MANAGEABLE_FLAG(type, name, value, doc)   ); emit_range_##type(#name
269#define EMIT_RANGE_PRODUCT_RW_FLAG(type, name, value, doc)   ); emit_range_##type(#name
270#define EMIT_RANGE_PD_PRODUCT_FLAG(type, name, doc)          ); emit_range_##type(#name
271#define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc)    ); emit_range_##type(#name
272#define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_range_##type(#name
273#define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_range_##type(#name
274#define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_range_##type(#name
275
276// Generate func argument to pass into emit_range_xxx functions
277#define EMIT_RANGE_CHECK(a, b)                               , a, b
278
279#define INITIAL_RANGES_SIZE 128
280GrowableArray<CommandLineFlagRange*>* CommandLineFlagRangeList::_ranges = NULL;
281
282// Check the ranges of all flags that have them
283void CommandLineFlagRangeList::init(void) {
284
285  _ranges = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagRange*>(INITIAL_RANGES_SIZE, true);
286
287  emit_range_no(NULL RUNTIME_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
288                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
289                                   EMIT_RANGE_PRODUCT_FLAG,
290                                   EMIT_RANGE_PD_PRODUCT_FLAG,
291                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
292                                   EMIT_RANGE_EXPERIMENTAL_FLAG,
293                                   EMIT_RANGE_NOTPRODUCT_FLAG,
294                                   EMIT_RANGE_MANAGEABLE_FLAG,
295                                   EMIT_RANGE_PRODUCT_RW_FLAG,
296                                   EMIT_RANGE_LP64_PRODUCT_FLAG,
297                                   EMIT_RANGE_CHECK,
298                                   IGNORE_CONSTRAINT) );
299
300  EMIT_RANGES_FOR_GLOBALS_EXT
301
302  emit_range_no(NULL ARCH_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
303                                     EMIT_RANGE_PRODUCT_FLAG,
304                                     EMIT_RANGE_DIAGNOSTIC_FLAG,
305                                     EMIT_RANGE_EXPERIMENTAL_FLAG,
306                                     EMIT_RANGE_NOTPRODUCT_FLAG,
307                                     EMIT_RANGE_CHECK,
308                                     IGNORE_CONSTRAINT));
309
310#ifdef COMPILER1
311  emit_range_no(NULL C1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
312                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
313                                   EMIT_RANGE_PRODUCT_FLAG,
314                                   EMIT_RANGE_PD_PRODUCT_FLAG,
315                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
316                                   EMIT_RANGE_NOTPRODUCT_FLAG,
317                                   EMIT_RANGE_CHECK,
318                                   IGNORE_CONSTRAINT));
319#endif // COMPILER1
320
321#ifdef COMPILER2
322  emit_range_no(NULL C2_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
323                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
324                                   EMIT_RANGE_PRODUCT_FLAG,
325                                   EMIT_RANGE_PD_PRODUCT_FLAG,
326                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
327                                   EMIT_RANGE_EXPERIMENTAL_FLAG,
328                                   EMIT_RANGE_NOTPRODUCT_FLAG,
329                                   EMIT_RANGE_CHECK,
330                                   IGNORE_CONSTRAINT));
331#endif // COMPILER2
332
333#if INCLUDE_ALL_GCS
334  emit_range_no(NULL G1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
335                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
336                                   EMIT_RANGE_PRODUCT_FLAG,
337                                   EMIT_RANGE_PD_PRODUCT_FLAG,
338                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
339                                   EMIT_RANGE_EXPERIMENTAL_FLAG,
340                                   EMIT_RANGE_NOTPRODUCT_FLAG,
341                                   EMIT_RANGE_MANAGEABLE_FLAG,
342                                   EMIT_RANGE_PRODUCT_RW_FLAG,
343                                   EMIT_RANGE_CHECK,
344                                   IGNORE_CONSTRAINT));
345#endif // INCLUDE_ALL_GCS
346}
347
348CommandLineFlagRange* CommandLineFlagRangeList::find(const char* name) {
349  CommandLineFlagRange* found = NULL;
350  for (int i=0; i<length(); i++) {
351    CommandLineFlagRange* range = at(i);
352    if (strcmp(range->name(), name) == 0) {
353      found = range;
354      break;
355    }
356  }
357  return found;
358}
359
360void CommandLineFlagRangeList::print(const char* name, outputStream* st, bool unspecified) {
361  CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
362  if (range != NULL) {
363    range->print(st);
364  } else if (unspecified == true) {
365    st->print("[                           ...                           ]");
366  }
367}
368