commandLineFlagRangeList.cpp revision 8638:767f36deb0dc
167754Smsmith/*
267754Smsmith * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
367754Smsmith * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
467754Smsmith *
567754Smsmith * This code is free software; you can redistribute it and/or modify it
667754Smsmith * under the terms of the GNU General Public License version 2 only, as
767754Smsmith * published by the Free Software Foundation.
8217365Sjkim *
9245582Sjkim * This code is distributed in the hope that it will be useful, but WITHOUT
1070243Smsmith * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1167754Smsmith * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12217365Sjkim * version 2 for more details (a copy is included in the LICENSE file that
13217365Sjkim * accompanied this code).
14217365Sjkim *
15217365Sjkim * You should have received a copy of the GNU General Public License version
16217365Sjkim * 2 along with this work; if not, write to the Free Software Foundation,
17217365Sjkim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18217365Sjkim *
19217365Sjkim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20217365Sjkim * or visit www.oracle.com if you need additional information or have any
21217365Sjkim * questions.
22217365Sjkim *
23217365Sjkim */
24217365Sjkim
25217365Sjkim#include "precompiled.hpp"
2667754Smsmith#include "classfile/stringTable.hpp"
27217365Sjkim#include "classfile/symbolTable.hpp"
28217365Sjkim#include "gc/shared/referenceProcessor.hpp"
29217365Sjkim#include "runtime/arguments.hpp"
3067754Smsmith#include "runtime/commandLineFlagRangeList.hpp"
31217365Sjkim#include "runtime/os.hpp"
32217365Sjkim#include "utilities/defaultStream.hpp"
33217365Sjkim#include "utilities/macros.hpp"
34217365Sjkim
35217365Sjkimclass CommandLineFlagRange_int : public CommandLineFlagRange {
36217365Sjkim  int _min;
37217365Sjkim  int _max;
38217365Sjkim
39217365Sjkimpublic:
40217365Sjkim  // the "name" argument must be a string literal
41217365Sjkim  CommandLineFlagRange_int(const char* name, int min, int max) : CommandLineFlagRange(name) {
42217365Sjkim    _min=min, _max=max;
43217365Sjkim  }
4467754Smsmith
4567754Smsmith  Flag::Error check_int(int value, bool verbose = true) {
4667754Smsmith    if ((value < _min) || (value > _max)) {
4767754Smsmith      if (verbose == true) {
48193341Sjkim        jio_fprintf(defaultStream::error_stream(),
49193341Sjkim                    "int %s=%d is outside the allowed range [ %d ... %d ]\n",
50193341Sjkim                    name(), value, _min, _max);
5167754Smsmith      }
5267754Smsmith      return Flag::OUT_OF_BOUNDS;
5377424Smsmith    } else {
5491116Smsmith      return Flag::SUCCESS;
5567754Smsmith    }
5667754Smsmith  }
5767754Smsmith
5867754Smsmith  void print(outputStream* st) {
5967754Smsmith    st->print("[ %-25d ... %25d ]", _min, _max);
6067754Smsmith  }
6182367Smsmith};
6267754Smsmith
6367754Smsmithclass CommandLineFlagRange_intx : public CommandLineFlagRange {
6482367Smsmith  intx _min;
6567754Smsmith  intx _max;
66151937Sjkim
67151937Sjkimpublic:
6867754Smsmith  // the "name" argument must be a string literal
69241973Sjkim  CommandLineFlagRange_intx(const char* name, intx min, intx max) : CommandLineFlagRange(name) {
7067754Smsmith    _min=min, _max=max;
7187031Smsmith  }
7287031Smsmith
7367754Smsmith  Flag::Error check_intx(intx value, bool verbose = true) {
7467754Smsmith    if ((value < _min) || (value > _max)) {
7567754Smsmith      if (verbose == true) {
7667754Smsmith        jio_fprintf(defaultStream::error_stream(),
7767754Smsmith                    "intx %s=" INTX_FORMAT " is outside the allowed range [ " INTX_FORMAT " ... " INTX_FORMAT " ]\n",
7867754Smsmith                    name(), value, _min, _max);
7967754Smsmith      }
8067754Smsmith      return Flag::OUT_OF_BOUNDS;
8167754Smsmith    } else {
8291116Smsmith      return Flag::SUCCESS;
8367754Smsmith    }
8467754Smsmith  }
8587031Smsmith
8691116Smsmith  void print(outputStream* st) {
8767754Smsmith    st->print("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", _min, _max);
8867754Smsmith  }
89167802Sjkim};
9067754Smsmith
9167754Smsmithclass CommandLineFlagRange_uint : public CommandLineFlagRange {
9267754Smsmith  uint _min;
9367754Smsmith  uint _max;
9467754Smsmith
9567754Smsmithpublic:
9667754Smsmith  // the "name" argument must be a string literal
9767754Smsmith  CommandLineFlagRange_uint(const char* name, uint min, uint max) : CommandLineFlagRange(name) {
9867754Smsmith    _min=min, _max=max;
99167802Sjkim  }
10067754Smsmith
10167754Smsmith  Flag::Error check_uint(uint value, bool verbose = true) {
10267754Smsmith    if ((value < _min) || (value > _max)) {
10367754Smsmith      if (verbose == true) {
10467754Smsmith        jio_fprintf(defaultStream::error_stream(),
10567754Smsmith                    "uintx %s=%u is outside the allowed range [ %u ... %u ]\n",
10667754Smsmith                    name(), value, _min, _max);
107167802Sjkim      }
108167802Sjkim      return Flag::OUT_OF_BOUNDS;
10967754Smsmith    } else {
11067754Smsmith      return Flag::SUCCESS;
11167754Smsmith    }
11291116Smsmith  }
11367754Smsmith
11467754Smsmith  void print(outputStream* st) {
11567754Smsmith    st->print("[ %-25u ... %25u ]", _min, _max);
116167802Sjkim  }
117167802Sjkim};
11867754Smsmith
11967754Smsmithclass CommandLineFlagRange_uintx : public CommandLineFlagRange {
12067754Smsmith  uintx _min;
12167754Smsmith  uintx _max;
12267754Smsmith
12367754Smsmithpublic:
12467754Smsmith  // the "name" argument must be a string literal
125151937Sjkim  CommandLineFlagRange_uintx(const char* name, uintx min, uintx max) : CommandLineFlagRange(name) {
126151937Sjkim    _min=min, _max=max;
12767754Smsmith  }
12867754Smsmith
12967754Smsmith  Flag::Error check_uintx(uintx value, bool verbose = true) {
13067754Smsmith    if ((value < _min) || (value > _max)) {
13167754Smsmith      if (verbose == true) {
13267754Smsmith        jio_fprintf(defaultStream::error_stream(),
13367754Smsmith                    "uintx %s=" UINTX_FORMAT " is outside the allowed range [ " UINTX_FORMAT " ... " UINTX_FORMAT " ]\n",
13467754Smsmith                    name(), value, _min, _max);
13567754Smsmith      }
13687031Smsmith      return Flag::OUT_OF_BOUNDS;
13787031Smsmith    } else {
13867754Smsmith      return Flag::SUCCESS;
13967754Smsmith    }
14067754Smsmith  }
14184491Smsmith
14267754Smsmith  void print(outputStream* st) {
14367754Smsmith    st->print("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", _min, _max);
14491116Smsmith  }
14567754Smsmith};
14667754Smsmith
14767754Smsmithclass CommandLineFlagRange_uint64_t : public CommandLineFlagRange {
14867754Smsmith  uint64_t _min;
149241973Sjkim  uint64_t _max;
15067754Smsmith
15187031Smsmithpublic:
15287031Smsmith  // the "name" argument must be a string literal
15367754Smsmith  CommandLineFlagRange_uint64_t(const char* name, uint64_t min, uint64_t max) : CommandLineFlagRange(name) {
15467754Smsmith    _min=min, _max=max;
15567754Smsmith  }
15667754Smsmith
15767754Smsmith  Flag::Error check_uint64_t(uint64_t value, bool verbose = true) {
15867754Smsmith    if ((value < _min) || (value > _max)) {
15967754Smsmith      if (verbose == true) {
16067754Smsmith        jio_fprintf(defaultStream::error_stream(),
16167754Smsmith                    "uint64_t %s=" UINT64_FORMAT " is outside the allowed range [ " UINT64_FORMAT " ... " UINT64_FORMAT " ]\n",
16267754Smsmith                    name(), value, _min, _max);
163107325Siwasaki      }
16467754Smsmith      return Flag::OUT_OF_BOUNDS;
165107325Siwasaki    } else {
16667754Smsmith      return Flag::SUCCESS;
16767754Smsmith    }
16882367Smsmith  }
169123315Snjl
17067754Smsmith  void print(outputStream* st) {
17187031Smsmith    st->print("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", _min, _max);
17267754Smsmith  }
17387031Smsmith};
17487031Smsmith
17587031Smsmithclass CommandLineFlagRange_size_t : public CommandLineFlagRange {
17687031Smsmith  size_t _min;
17767754Smsmith  size_t _max;
17899679Siwasaki
17967754Smsmithpublic:
18099679Siwasaki  // the "name" argument must be a string literal
18199679Siwasaki  CommandLineFlagRange_size_t(const char* name, size_t min, size_t max) : CommandLineFlagRange(name) {
18299679Siwasaki    _min=min, _max=max;
18399679Siwasaki  }
18499679Siwasaki
18567754Smsmith  Flag::Error check_size_t(size_t value, bool verbose = true) {
18699679Siwasaki    if ((value < _min) || (value > _max)) {
18799679Siwasaki      if (verbose == true) {
18899679Siwasaki        jio_fprintf(defaultStream::error_stream(),
18999679Siwasaki                    "size_t %s=" SIZE_FORMAT " is outside the allowed range [ " SIZE_FORMAT " ... " SIZE_FORMAT " ]\n",
19099679Siwasaki                    name(), value, _min, _max);
19199679Siwasaki      }
19299679Siwasaki      return Flag::OUT_OF_BOUNDS;
19399679Siwasaki    } else {
19499679Siwasaki      return Flag::SUCCESS;
19567754Smsmith    }
19699679Siwasaki  }
19767754Smsmith
19899679Siwasaki  void print(outputStream* st) {
19999679Siwasaki    st->print("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", _min, _max);
20099679Siwasaki  }
20187031Smsmith};
20287031Smsmith
20367754Smsmithclass CommandLineFlagRange_double : public CommandLineFlagRange {
20467754Smsmith  double _min;
20567754Smsmith  double _max;
20667754Smsmith
20767754Smsmithpublic:
20867754Smsmith  // the "name" argument must be a string literal
20967754Smsmith  CommandLineFlagRange_double(const char* name, double min, double max) : CommandLineFlagRange(name) {
21067754Smsmith    _min=min, _max=max;
21167754Smsmith  }
212151937Sjkim
21367754Smsmith  Flag::Error check_double(double value, bool verbose = true) {
21467754Smsmith    if ((value < _min) || (value > _max)) {
21567754Smsmith      if (verbose == true) {
216114237Snjl        jio_fprintf(defaultStream::error_stream(),
217107325Siwasaki                    "double %s=%f is outside the allowed range [ %f ... %f ]\n",
218107325Siwasaki                    name(), value, _min, _max);
21967754Smsmith      }
22067754Smsmith      return Flag::OUT_OF_BOUNDS;
22167754Smsmith    } else {
22267754Smsmith      return Flag::SUCCESS;
22367754Smsmith    }
22467754Smsmith  }
22567754Smsmith
22667754Smsmith  void print(outputStream* st) {
22767754Smsmith    st->print("[ %-25.3f ... %25.3f ]", _min, _max);
22867754Smsmith  }
229167802Sjkim};
23067754Smsmith
23183174Smsmith// No constraint emitting
23267754Smsmithvoid emit_range_no(...)                         { /* NOP */ }
23399679Siwasaki
23499679Siwasaki// No constraint emitting if function argument is NOT provided
235193267Sjkimvoid emit_range_bool(const char* /*name*/)      { /* NOP */ }
23667754Smsmithvoid emit_range_ccstr(const char* /*name*/)     { /* NOP */ }
23767754Smsmithvoid emit_range_ccstrlist(const char* /*name*/) { /* NOP */ }
23867754Smsmithvoid emit_range_int(const char* /*name*/)       { /* NOP */ }
23967754Smsmithvoid emit_range_intx(const char* /*name*/)      { /* NOP */ }
240193267Sjkimvoid emit_range_uint(const char* /*name*/)      { /* NOP */ }
241193267Sjkimvoid emit_range_uintx(const char* /*name*/)     { /* NOP */ }
242193267Sjkimvoid emit_range_uint64_t(const char* /*name*/)  { /* NOP */ }
243193267Sjkimvoid emit_range_size_t(const char* /*name*/)    { /* NOP */ }
244193267Sjkimvoid emit_range_double(const char* /*name*/)    { /* NOP */ }
245193267Sjkim
246193267Sjkim// CommandLineFlagRange emitting code functions if range arguments are provided
247193267Sjkimvoid emit_range_intx(const char* name, intx min, intx max) {
248193267Sjkim  CommandLineFlagRangeList::add(new CommandLineFlagRange_intx(name, min, max));
249193267Sjkim}
25067754Smsmithvoid emit_range_uintx(const char* name, uintx min, uintx max) {
25167754Smsmith  CommandLineFlagRangeList::add(new CommandLineFlagRange_uintx(name, min, max));
25267754Smsmith}
25399679Siwasakivoid emit_range_uint64_t(const char* name, uint64_t min, uint64_t max) {
25487031Smsmith  CommandLineFlagRangeList::add(new CommandLineFlagRange_uint64_t(name, min, max));
25587031Smsmith}
25687031Smsmithvoid emit_range_size_t(const char* name, size_t min, size_t max) {
257193267Sjkim  CommandLineFlagRangeList::add(new CommandLineFlagRange_size_t(name, min, max));
25887031Smsmith}
25987031Smsmithvoid emit_range_double(const char* name, double min, double max) {
26087031Smsmith  CommandLineFlagRangeList::add(new CommandLineFlagRange_double(name, min, max));
26187031Smsmith}
26267754Smsmith
26387031Smsmith// Generate code to call emit_range_xxx function
26487031Smsmith#define EMIT_RANGE_PRODUCT_FLAG(type, name, value, doc)      ); emit_range_##type(#name
26587031Smsmith#define EMIT_RANGE_COMMERCIAL_FLAG(type, name, value, doc)   ); emit_range_##type(#name
26687031Smsmith#define EMIT_RANGE_DIAGNOSTIC_FLAG(type, name, value, doc)   ); emit_range_##type(#name
26799146Siwasaki#define EMIT_RANGE_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_range_##type(#name
268123315Snjl#define EMIT_RANGE_MANAGEABLE_FLAG(type, name, value, doc)   ); emit_range_##type(#name
26967754Smsmith#define EMIT_RANGE_PRODUCT_RW_FLAG(type, name, value, doc)   ); emit_range_##type(#name
27085756Smsmith#define EMIT_RANGE_PD_PRODUCT_FLAG(type, name, doc)          ); emit_range_##type(#name
27167754Smsmith#define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc)    ); emit_range_##type(#name
27285756Smsmith#define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_range_##type(#name
27367754Smsmith#define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_range_##type(#name
27467754Smsmith#define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_range_##type(#name
27567754Smsmith
27667754Smsmith// Generate func argument to pass into emit_range_xxx functions
27767754Smsmith#define EMIT_RANGE_CHECK(a, b)                               , a, b
27867754Smsmith
27967754Smsmith#define INITIAL_RANGES_SIZE 128
28067754SmsmithGrowableArray<CommandLineFlagRange*>* CommandLineFlagRangeList::_ranges = NULL;
281151937Sjkim
28267754Smsmith// Check the ranges of all flags that have them
28367754Smsmithvoid CommandLineFlagRangeList::init(void) {
28467754Smsmith
28567754Smsmith  _ranges = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagRange*>(INITIAL_RANGES_SIZE, true);
286107325Siwasaki
287107325Siwasaki  emit_range_no(NULL RUNTIME_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
28867754Smsmith                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
28967754Smsmith                                   EMIT_RANGE_PRODUCT_FLAG,
29087031Smsmith                                   EMIT_RANGE_PD_PRODUCT_FLAG,
29167754Smsmith                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
29277424Smsmith                                   EMIT_RANGE_EXPERIMENTAL_FLAG,
29367754Smsmith                                   EMIT_RANGE_NOTPRODUCT_FLAG,
294167802Sjkim                                   EMIT_RANGE_MANAGEABLE_FLAG,
29567754Smsmith                                   EMIT_RANGE_PRODUCT_RW_FLAG,
29667754Smsmith                                   EMIT_RANGE_LP64_PRODUCT_FLAG,
29777424Smsmith                                   EMIT_RANGE_CHECK,
29867754Smsmith                                   IGNORE_CONSTRAINT) );
299167802Sjkim
30067754Smsmith  EMIT_RANGES_FOR_GLOBALS_EXT
30167754Smsmith
30267754Smsmith  emit_range_no(NULL ARCH_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
30387031Smsmith                                     EMIT_RANGE_PRODUCT_FLAG,
30499679Siwasaki                                     EMIT_RANGE_DIAGNOSTIC_FLAG,
30599679Siwasaki                                     EMIT_RANGE_EXPERIMENTAL_FLAG,
306193267Sjkim                                     EMIT_RANGE_NOTPRODUCT_FLAG,
30787031Smsmith                                     EMIT_RANGE_CHECK,
30887031Smsmith                                     IGNORE_CONSTRAINT));
30987031Smsmith
31087031Smsmith#ifdef COMPILER1
31177424Smsmith  emit_range_no(NULL C1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
31267754Smsmith                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
31367754Smsmith                                   EMIT_RANGE_PRODUCT_FLAG,
31467754Smsmith                                   EMIT_RANGE_PD_PRODUCT_FLAG,
31587031Smsmith                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
31687031Smsmith                                   EMIT_RANGE_NOTPRODUCT_FLAG,
31787031Smsmith                                   EMIT_RANGE_CHECK,
31887031Smsmith                                   IGNORE_CONSTRAINT));
319151937Sjkim#endif // COMPILER1
32087031Smsmith
32187031Smsmith#ifdef COMPILER2
322107325Siwasaki  emit_range_no(NULL C2_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
32387031Smsmith                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
324107325Siwasaki                                   EMIT_RANGE_PRODUCT_FLAG,
325107325Siwasaki                                   EMIT_RANGE_PD_PRODUCT_FLAG,
32687031Smsmith                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
32787031Smsmith                                   EMIT_RANGE_EXPERIMENTAL_FLAG,
32887031Smsmith                                   EMIT_RANGE_NOTPRODUCT_FLAG,
32987031Smsmith                                   EMIT_RANGE_CHECK,
33087031Smsmith                                   IGNORE_CONSTRAINT));
33187031Smsmith#endif // COMPILER2
332167802Sjkim
33387031Smsmith#if INCLUDE_ALL_GCS
33487031Smsmith  emit_range_no(NULL G1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
335193267Sjkim                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
336193267Sjkim                                   EMIT_RANGE_PRODUCT_FLAG,
337193267Sjkim                                   EMIT_RANGE_PD_PRODUCT_FLAG,
338193267Sjkim                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
33987031Smsmith                                   EMIT_RANGE_EXPERIMENTAL_FLAG,
34087031Smsmith                                   EMIT_RANGE_NOTPRODUCT_FLAG,
34187031Smsmith                                   EMIT_RANGE_MANAGEABLE_FLAG,
34287031Smsmith                                   EMIT_RANGE_PRODUCT_RW_FLAG,
34387031Smsmith                                   EMIT_RANGE_CHECK,
34487031Smsmith                                   IGNORE_CONSTRAINT));
34587031Smsmith#endif // INCLUDE_ALL_GCS
34687031Smsmith}
34787031Smsmith
34887031SmsmithCommandLineFlagRange* CommandLineFlagRangeList::find(const char* name) {
34987031Smsmith  CommandLineFlagRange* found = NULL;
35087031Smsmith  for (int i=0; i<length(); i++) {
351107325Siwasaki    CommandLineFlagRange* range = at(i);
352107325Siwasaki    if (strcmp(range->name(), name) == 0) {
353107325Siwasaki      found = range;
35487031Smsmith      break;
35587031Smsmith    }
35687031Smsmith  }
357241973Sjkim  return found;
35887031Smsmith}
35987031Smsmith
36087031Smsmithvoid CommandLineFlagRangeList::print(const char* name, outputStream* st, bool unspecified) {
36187031Smsmith  CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
36287031Smsmith  if (range != NULL) {
36387031Smsmith    range->print(st);
36487031Smsmith  } else if (unspecified == true) {
36587031Smsmith    st->print("[                           ...                           ]");
36687031Smsmith  }
36787031Smsmith}
36887031Smsmith