1 /*
   2  * Copyright (c) 2015, 2016, 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/commandLineFlagConstraintList.hpp"
  31 #include "runtime/commandLineFlagRangeList.hpp"
  32 #include "runtime/os.hpp"
  33 #include "runtime/task.hpp"
  34 #include "utilities/defaultStream.hpp"
  35 #include "utilities/macros.hpp"
  36 
  37 void CommandLineError::print(bool verbose, const char* msg, ...) {
  38   if (verbose) {
  39     va_list listPointer;
  40     va_start(listPointer, msg);
  41     jio_vfprintf(defaultStream::error_stream(), msg, listPointer);
  42     va_end(listPointer);
  43   }
  44 }
  45 
  46 class CommandLineFlagRange_int : public CommandLineFlagRange {
  47   int _min;
  48   int _max;
  49   const int* _ptr;
  50 
  51 public:
  52   // the "name" argument must be a string literal
  53   CommandLineFlagRange_int(const char* name, const int* ptr, int min, int max)
  54     : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
  55 
  56   Flag::Error check(bool verbose = true) {
  57     return check_int(*_ptr, verbose);
  58   }
  59 
  60   Flag::Error check_int(int value, bool verbose = true) {
  61     if ((value < _min) || (value > _max)) {
  62       CommandLineError::print(verbose,
  63                               "int %s=%d is outside the allowed range "
  64                               "[ %d ... %d ]\n",
  65                               name(), value, _min, _max);
  66       return Flag::OUT_OF_BOUNDS;
  67     } else {
  68       return Flag::SUCCESS;
  69     }
  70   }
  71 
  72   void print(outputStream* st) {
  73     st->print("[ %-25d ... %25d ]", _min, _max);
  74   }
  75 };
  76 
  77 class CommandLineFlagRange_intx : public CommandLineFlagRange {
  78   intx _min;
  79   intx _max;
  80   const intx* _ptr;
  81 public:
  82   // the "name" argument must be a string literal
  83   CommandLineFlagRange_intx(const char* name, const intx* ptr, intx min, intx max)
  84     : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
  85 
  86   Flag::Error check(bool verbose = true) {
  87     return check_intx(*_ptr, verbose);
  88   }
  89 
  90   Flag::Error check_intx(intx value, bool verbose = true) {
  91     if ((value < _min) || (value > _max)) {
  92       CommandLineError::print(verbose,
  93                               "intx %s=" INTX_FORMAT " is outside the allowed range "
  94                               "[ " INTX_FORMAT " ... " INTX_FORMAT " ]\n",
  95                               name(), value, _min, _max);
  96       return Flag::OUT_OF_BOUNDS;
  97     } else {
  98       return Flag::SUCCESS;
  99     }
 100   }
 101 
 102   void print(outputStream* st) {
 103     st->print("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", _min, _max);
 104   }
 105 };
 106 
 107 class CommandLineFlagRange_uint : public CommandLineFlagRange {
 108   uint _min;
 109   uint _max;
 110   const uint* _ptr;
 111 
 112 public:
 113   // the "name" argument must be a string literal
 114   CommandLineFlagRange_uint(const char* name, const uint* ptr, uint min, uint max)
 115     : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
 116 
 117   Flag::Error check(bool verbose = true) {
 118     return check_uint(*_ptr, verbose);
 119   }
 120 
 121   Flag::Error check_uint(uint value, bool verbose = true) {
 122     if ((value < _min) || (value > _max)) {
 123       CommandLineError::print(verbose,
 124                               "uint %s=%u is outside the allowed range "
 125                               "[ %u ... %u ]\n",
 126                               name(), value, _min, _max);
 127       return Flag::OUT_OF_BOUNDS;
 128     } else {
 129       return Flag::SUCCESS;
 130     }
 131   }
 132 
 133   void print(outputStream* st) {
 134     st->print("[ %-25u ... %25u ]", _min, _max);
 135   }
 136 };
 137 
 138 class CommandLineFlagRange_uintx : public CommandLineFlagRange {
 139   uintx _min;
 140   uintx _max;
 141   const uintx* _ptr;
 142 
 143 public:
 144   // the "name" argument must be a string literal
 145   CommandLineFlagRange_uintx(const char* name, const uintx* ptr, uintx min, uintx max)
 146     : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
 147 
 148   Flag::Error check(bool verbose = true) {
 149     return check_uintx(*_ptr, verbose);
 150   }
 151 
 152   Flag::Error check_uintx(uintx value, bool verbose = true) {
 153     if ((value < _min) || (value > _max)) {
 154       CommandLineError::print(verbose,
 155                               "uintx %s=" UINTX_FORMAT " is outside the allowed range "
 156                               "[ " UINTX_FORMAT " ... " UINTX_FORMAT " ]\n",
 157                               name(), value, _min, _max);
 158       return Flag::OUT_OF_BOUNDS;
 159     } else {
 160       return Flag::SUCCESS;
 161     }
 162   }
 163 
 164   void print(outputStream* st) {
 165     st->print("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", _min, _max);
 166   }
 167 };
 168 
 169 class CommandLineFlagRange_uint64_t : public CommandLineFlagRange {
 170   uint64_t _min;
 171   uint64_t _max;
 172   const uint64_t* _ptr;
 173 
 174 public:
 175   // the "name" argument must be a string literal
 176   CommandLineFlagRange_uint64_t(const char* name, const uint64_t* ptr, uint64_t min, uint64_t max)
 177     : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
 178 
 179   Flag::Error check(bool verbose = true) {
 180     return check_uint64_t(*_ptr, verbose);
 181   }
 182 
 183   Flag::Error check_uint64_t(uint64_t value, bool verbose = true) {
 184     if ((value < _min) || (value > _max)) {
 185       CommandLineError::print(verbose,
 186                               "uint64_t %s=" UINT64_FORMAT " is outside the allowed range "
 187                               "[ " UINT64_FORMAT " ... " UINT64_FORMAT " ]\n",
 188                               name(), value, _min, _max);
 189       return Flag::OUT_OF_BOUNDS;
 190     } else {
 191       return Flag::SUCCESS;
 192     }
 193   }
 194 
 195   void print(outputStream* st) {
 196     st->print("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", _min, _max);
 197   }
 198 };
 199 
 200 class CommandLineFlagRange_size_t : public CommandLineFlagRange {
 201   size_t _min;
 202   size_t _max;
 203   const size_t* _ptr;
 204 
 205 public:
 206   // the "name" argument must be a string literal
 207   CommandLineFlagRange_size_t(const char* name, const size_t* ptr, size_t min, size_t max)
 208     : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
 209 
 210   Flag::Error check(bool verbose = true) {
 211     return check_size_t(*_ptr, verbose);
 212   }
 213 
 214   Flag::Error check_size_t(size_t value, bool verbose = true) {
 215     if ((value < _min) || (value > _max)) {
 216       CommandLineError::print(verbose,
 217                               "size_t %s=" SIZE_FORMAT " is outside the allowed range "
 218                               "[ " SIZE_FORMAT " ... " SIZE_FORMAT " ]\n",
 219                               name(), value, _min, _max);
 220       return Flag::OUT_OF_BOUNDS;
 221     } else {
 222       return Flag::SUCCESS;
 223     }
 224   }
 225 
 226   void print(outputStream* st) {
 227     st->print("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", _min, _max);
 228   }
 229 };
 230 
 231 class CommandLineFlagRange_double : public CommandLineFlagRange {
 232   double _min;
 233   double _max;
 234   const double* _ptr;
 235 
 236 public:
 237   // the "name" argument must be a string literal
 238   CommandLineFlagRange_double(const char* name, const double* ptr, double min, double max)
 239     : CommandLineFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
 240 
 241   Flag::Error check(bool verbose = true) {
 242     return check_double(*_ptr, verbose);
 243   }
 244 
 245   Flag::Error check_double(double value, bool verbose = true) {
 246     if ((value < _min) || (value > _max)) {
 247       CommandLineError::print(verbose,
 248                               "double %s=%f is outside the allowed range "
 249                               "[ %f ... %f ]\n",
 250                               name(), value, _min, _max);
 251       return Flag::OUT_OF_BOUNDS;
 252     } else {
 253       return Flag::SUCCESS;
 254     }
 255   }
 256 
 257   void print(outputStream* st) {
 258     st->print("[ %-25.3f ... %25.3f ]", _min, _max);
 259   }
 260 };
 261 
 262 // No constraint emitting
 263 void emit_range_no(...)                         { /* NOP */ }
 264 
 265 // No constraint emitting if function argument is NOT provided
 266 void emit_range_bool(const char* /*name*/, const bool* /*value*/)            { /* NOP */ }
 267 void emit_range_ccstr(const char* /*name*/, const ccstr* /*value*/)          { /* NOP */ }
 268 void emit_range_ccstrlist(const char* /*name*/, const ccstrlist* /*value*/)  { /* NOP */ }
 269 void emit_range_int(const char* /*name*/, const int* /*value*/)              { /* NOP */ }
 270 void emit_range_intx(const char* /*name*/, const intx* /*value*/)            { /* NOP */ }
 271 void emit_range_uint(const char* /*name*/, const uint* /*value*/)            { /* NOP */ }
 272 void emit_range_uintx(const char* /*name*/, const uintx* /*value*/)          { /* NOP */ }
 273 void emit_range_uint64_t(const char* /*name*/, const uint64_t* /*value*/)    { /* NOP */ }
 274 void emit_range_size_t(const char* /*name*/, const size_t* /*value*/)        { /* NOP */ }
 275 void emit_range_double(const char* /*name*/, const double* /*value*/)        { /* NOP */ }
 276 
 277 // CommandLineFlagRange emitting code functions if range arguments are provided
 278 void emit_range_int(const char* name, const int* ptr, int min, int max)       {
 279   CommandLineFlagRangeList::add(new CommandLineFlagRange_int(name, ptr, min, max));
 280 }
 281 void emit_range_intx(const char* name, const intx* ptr, intx min, intx max) {
 282   CommandLineFlagRangeList::add(new CommandLineFlagRange_intx(name, ptr, min, max));
 283 }
 284 void emit_range_uint(const char* name, const uint* ptr, uint min, uint max) {
 285   CommandLineFlagRangeList::add(new CommandLineFlagRange_uint(name, ptr, min, max));
 286 }
 287 void emit_range_uintx(const char* name, const uintx* ptr, uintx min, uintx max) {
 288   CommandLineFlagRangeList::add(new CommandLineFlagRange_uintx(name, ptr, min, max));
 289 }
 290 void emit_range_uint64_t(const char* name, const uint64_t* ptr, uint64_t min, uint64_t max) {
 291   CommandLineFlagRangeList::add(new CommandLineFlagRange_uint64_t(name, ptr, min, max));
 292 }
 293 void emit_range_size_t(const char* name, const size_t* ptr, size_t min, size_t max) {
 294   CommandLineFlagRangeList::add(new CommandLineFlagRange_size_t(name, ptr, min, max));
 295 }
 296 void emit_range_double(const char* name, const double* ptr, double min, double max) {
 297   CommandLineFlagRangeList::add(new CommandLineFlagRange_double(name, ptr, min, max));
 298 }
 299 
 300 // Generate code to call emit_range_xxx function
 301 #define EMIT_RANGE_PRODUCT_FLAG(type, name, value, doc)      ); emit_range_##type(#name,&name
 302 #define EMIT_RANGE_COMMERCIAL_FLAG(type, name, value, doc)   ); emit_range_##type(#name,&name
 303 #define EMIT_RANGE_DIAGNOSTIC_FLAG(type, name, value, doc)   ); emit_range_##type(#name,&name
 304 #define EMIT_RANGE_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name
 305 #define EMIT_RANGE_MANAGEABLE_FLAG(type, name, value, doc)   ); emit_range_##type(#name,&name
 306 #define EMIT_RANGE_PRODUCT_RW_FLAG(type, name, value, doc)   ); emit_range_##type(#name,&name
 307 #define EMIT_RANGE_PD_PRODUCT_FLAG(type, name, doc)          ); emit_range_##type(#name,&name
 308 #define EMIT_RANGE_PD_DIAGNOSTIC_FLAG(type, name, doc)       ); emit_range_##type(#name,&name
 309 #ifndef PRODUCT
 310 #define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc)    ); emit_range_##type(#name,&name
 311 #define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_range_##type(#name,&name
 312 #define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_range_##type(#name,&name
 313 #else
 314 #define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc)    ); emit_range_no(#name,&name
 315 #define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_range_no(#name,&name
 316 #define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_range_no(#name,&name
 317 #endif
 318 #ifdef _LP64
 319 #define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_range_##type(#name,&name
 320 #else
 321 #define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_range_no(#name,&name
 322 #endif
 323 
 324 // Generate func argument to pass into emit_range_xxx functions
 325 #define EMIT_RANGE_CHECK(a, b)                               , a, b
 326 
 327 #define INITIAL_RANGES_SIZE 379
 328 GrowableArray<CommandLineFlagRange*>* CommandLineFlagRangeList::_ranges = NULL;
 329 
 330 // Check the ranges of all flags that have them
 331 void CommandLineFlagRangeList::init(void) {
 332 
 333   _ranges = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<CommandLineFlagRange*>(INITIAL_RANGES_SIZE, true);
 334 
 335   emit_range_no(NULL RUNTIME_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
 336                                    EMIT_RANGE_PD_DEVELOPER_FLAG,
 337                                    EMIT_RANGE_PRODUCT_FLAG,
 338                                    EMIT_RANGE_PD_PRODUCT_FLAG,
 339                                    EMIT_RANGE_DIAGNOSTIC_FLAG,
 340                                    EMIT_RANGE_PD_DIAGNOSTIC_FLAG,
 341                                    EMIT_RANGE_EXPERIMENTAL_FLAG,
 342                                    EMIT_RANGE_NOTPRODUCT_FLAG,
 343                                    EMIT_RANGE_MANAGEABLE_FLAG,
 344                                    EMIT_RANGE_PRODUCT_RW_FLAG,
 345                                    EMIT_RANGE_LP64_PRODUCT_FLAG,
 346                                    EMIT_RANGE_CHECK,
 347                                    IGNORE_CONSTRAINT,
 348                                    IGNORE_WRITEABLE));
 349 
 350   EMIT_RANGES_FOR_GLOBALS_EXT
 351 
 352   emit_range_no(NULL ARCH_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
 353                                 EMIT_RANGE_PRODUCT_FLAG,
 354                                 EMIT_RANGE_DIAGNOSTIC_FLAG,
 355                                 EMIT_RANGE_EXPERIMENTAL_FLAG,
 356                                 EMIT_RANGE_NOTPRODUCT_FLAG,
 357                                 EMIT_RANGE_CHECK,
 358                                 IGNORE_CONSTRAINT,
 359                                 IGNORE_WRITEABLE));
 360 
 361 #if INCLUDE_JVMCI
 362   emit_range_no(NULL JVMCI_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
 363                                  EMIT_RANGE_PD_DEVELOPER_FLAG,
 364                                  EMIT_RANGE_PRODUCT_FLAG,
 365                                  EMIT_RANGE_PD_PRODUCT_FLAG,
 366                                  EMIT_RANGE_DIAGNOSTIC_FLAG,
 367                                  EMIT_RANGE_PD_DIAGNOSTIC_FLAG,
 368                                  EMIT_RANGE_EXPERIMENTAL_FLAG,
 369                                  EMIT_RANGE_NOTPRODUCT_FLAG,
 370                                  EMIT_RANGE_CHECK,
 371                                  IGNORE_CONSTRAINT,
 372                                  IGNORE_WRITEABLE));
 373 #endif // INCLUDE_JVMCI
 374 
 375 #ifdef COMPILER1
 376   emit_range_no(NULL C1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
 377                               EMIT_RANGE_PD_DEVELOPER_FLAG,
 378                               EMIT_RANGE_PRODUCT_FLAG,
 379                               EMIT_RANGE_PD_PRODUCT_FLAG,
 380                               EMIT_RANGE_DIAGNOSTIC_FLAG,
 381                               EMIT_RANGE_PD_DIAGNOSTIC_FLAG,
 382                               EMIT_RANGE_NOTPRODUCT_FLAG,
 383                               EMIT_RANGE_CHECK,
 384                               IGNORE_CONSTRAINT,
 385                               IGNORE_WRITEABLE));
 386 #endif // COMPILER1
 387 
 388 #ifdef COMPILER2
 389   emit_range_no(NULL C2_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
 390                               EMIT_RANGE_PD_DEVELOPER_FLAG,
 391                               EMIT_RANGE_PRODUCT_FLAG,
 392                               EMIT_RANGE_PD_PRODUCT_FLAG,
 393                               EMIT_RANGE_DIAGNOSTIC_FLAG,
 394                               EMIT_RANGE_PD_DIAGNOSTIC_FLAG,
 395                               EMIT_RANGE_EXPERIMENTAL_FLAG,
 396                               EMIT_RANGE_NOTPRODUCT_FLAG,
 397                               EMIT_RANGE_CHECK,
 398                               IGNORE_CONSTRAINT,
 399                               IGNORE_WRITEABLE));
 400 #endif // COMPILER2
 401 
 402 #if INCLUDE_ALL_GCS
 403   emit_range_no(NULL G1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
 404                               EMIT_RANGE_PD_DEVELOPER_FLAG,
 405                               EMIT_RANGE_PRODUCT_FLAG,
 406                               EMIT_RANGE_PD_PRODUCT_FLAG,
 407                               EMIT_RANGE_DIAGNOSTIC_FLAG,
 408                               EMIT_RANGE_PD_DIAGNOSTIC_FLAG,
 409                               EMIT_RANGE_EXPERIMENTAL_FLAG,
 410                               EMIT_RANGE_NOTPRODUCT_FLAG,
 411                               EMIT_RANGE_MANAGEABLE_FLAG,
 412                               EMIT_RANGE_PRODUCT_RW_FLAG,
 413                               EMIT_RANGE_CHECK,
 414                               IGNORE_CONSTRAINT,
 415                               IGNORE_WRITEABLE));
 416 #endif // INCLUDE_ALL_GCS
 417 }
 418 
 419 CommandLineFlagRange* CommandLineFlagRangeList::find(const char* name) {
 420   CommandLineFlagRange* found = NULL;
 421   for (int i=0; i<length(); i++) {
 422     CommandLineFlagRange* range = at(i);
 423     if (strcmp(range->name(), name) == 0) {
 424       found = range;
 425       break;
 426     }
 427   }
 428   return found;
 429 }
 430 
 431 void CommandLineFlagRangeList::print(outputStream* st, const char* name, RangeStrFunc default_range_str_func) {
 432   CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
 433   if (range != NULL) {
 434     range->print(st);
 435   } else {
 436     CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
 437     if (constraint != NULL) {
 438       assert(default_range_str_func!=NULL, "default_range_str_func must be provided");
 439       st->print("%s", default_range_str_func());
 440     } else {
 441       st->print("[                           ...                           ]");
 442     }
 443   }
 444 }
 445 
 446 bool CommandLineFlagRangeList::check_ranges() {
 447   // Check ranges.
 448   bool status = true;
 449   for (int i=0; i<length(); i++) {
 450     CommandLineFlagRange* range = at(i);
 451     if (range->check(true) != Flag::SUCCESS) status = false;
 452   }
 453   return status;
 454 }