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/commandLineFlagConstraintList.hpp"
  31 #include "runtime/commandLineFlagConstraintsCompiler.hpp"
  32 #include "runtime/commandLineFlagConstraintsGC.hpp"
  33 #include "runtime/commandLineFlagConstraintsRuntime.hpp"
  34 #include "runtime/os_ext.hpp"
  35 #include "utilities/macros.hpp"
  36 
  37 class CommandLineFlagConstraint_bool : public CommandLineFlagConstraint {
  38   CommandLineFlagConstraintFunc_bool _constraint;
  39 
  40 public:
  41   CommandLineFlagConstraint_bool(const char* name, CommandLineFlagConstraintFunc_bool func) : CommandLineFlagConstraint(name) {
  42     _constraint=func;
  43   }
  44 
  45   Flag::Error apply_bool(bool* value, bool verbose) {
  46     return _constraint(verbose, value);
  47   }
  48 };
  49 
  50 class CommandLineFlagConstraint_int : public CommandLineFlagConstraint {
  51   CommandLineFlagConstraintFunc_int _constraint;
  52 
  53 public:
  54   CommandLineFlagConstraint_int(const char* name, CommandLineFlagConstraintFunc_int func) : CommandLineFlagConstraint(name) {
  55     _constraint=func;
  56   }
  57 
  58   Flag::Error apply_int(int* value, bool verbose) {
  59     return _constraint(verbose, value);
  60   }
  61 };
  62 
  63 class CommandLineFlagConstraint_intx : public CommandLineFlagConstraint {
  64   CommandLineFlagConstraintFunc_intx _constraint;
  65 
  66 public:
  67   CommandLineFlagConstraint_intx(const char* name, CommandLineFlagConstraintFunc_intx func) : CommandLineFlagConstraint(name) {
  68     _constraint=func;
  69   }
  70 
  71   Flag::Error apply_intx(intx* value, bool verbose) {
  72     return _constraint(verbose, value);
  73   }
  74 };
  75 
  76 class CommandLineFlagConstraint_uint : public CommandLineFlagConstraint {
  77   CommandLineFlagConstraintFunc_uint _constraint;
  78 
  79 public:
  80   CommandLineFlagConstraint_uint(const char* name, CommandLineFlagConstraintFunc_uint func) : CommandLineFlagConstraint(name) {
  81     _constraint=func;
  82   }
  83 
  84   Flag::Error apply_uint(uint* value, bool verbose) {
  85     return _constraint(verbose, value);
  86   }
  87 };
  88 
  89 class CommandLineFlagConstraint_uintx : public CommandLineFlagConstraint {
  90   CommandLineFlagConstraintFunc_uintx _constraint;
  91 
  92 public:
  93   CommandLineFlagConstraint_uintx(const char* name, CommandLineFlagConstraintFunc_uintx func) : CommandLineFlagConstraint(name) {
  94     _constraint=func;
  95   }
  96 
  97   Flag::Error apply_uintx(uintx* value, bool verbose) {
  98     return _constraint(verbose, value);
  99   }
 100 };
 101 
 102 class CommandLineFlagConstraint_uint64_t : public CommandLineFlagConstraint {
 103   CommandLineFlagConstraintFunc_uint64_t _constraint;
 104 
 105 public:
 106   CommandLineFlagConstraint_uint64_t(const char* name, CommandLineFlagConstraintFunc_uint64_t func) : CommandLineFlagConstraint(name) {
 107     _constraint=func;
 108   }
 109 
 110   Flag::Error apply_uint64_t(uint64_t* value, bool verbose) {
 111     return _constraint(verbose, value);
 112   }
 113 };
 114 
 115 class CommandLineFlagConstraint_size_t : public CommandLineFlagConstraint {
 116   CommandLineFlagConstraintFunc_size_t _constraint;
 117 
 118 public:
 119   CommandLineFlagConstraint_size_t(const char* name, CommandLineFlagConstraintFunc_size_t func) : CommandLineFlagConstraint(name) {
 120     _constraint=func;
 121   }
 122 
 123   Flag::Error apply_size_t(size_t* value, bool verbose) {
 124     return _constraint(verbose, value);
 125   }
 126 };
 127 
 128 class CommandLineFlagConstraint_double : public CommandLineFlagConstraint {
 129   CommandLineFlagConstraintFunc_double _constraint;
 130 
 131 public:
 132   CommandLineFlagConstraint_double(const char* name, CommandLineFlagConstraintFunc_double func) : CommandLineFlagConstraint(name) {
 133     _constraint=func;
 134   }
 135 
 136   Flag::Error apply_double(double* value, bool verbose) {
 137     return _constraint(verbose, value);
 138   }
 139 };
 140 
 141 // No constraint emitting
 142 void emit_constraint_no(...)                          { /* NOP */ }
 143 
 144 // No constraint emitting if function argument is NOT provided
 145 void emit_constraint_bool(const char* /*name*/)       { /* NOP */ }
 146 void emit_constraint_ccstr(const char* /*name*/)      { /* NOP */ }
 147 void emit_constraint_ccstrlist(const char* /*name*/)  { /* NOP */ }
 148 void emit_constraint_int(const char* /*name*/)        { /* NOP */ }
 149 void emit_constraint_intx(const char* /*name*/)       { /* NOP */ }
 150 void emit_constraint_uint(const char* /*name*/)       { /* NOP */ }
 151 void emit_constraint_uintx(const char* /*name*/)      { /* NOP */ }
 152 void emit_constraint_uint64_t(const char* /*name*/)   { /* NOP */ }
 153 void emit_constraint_size_t(const char* /*name*/)     { /* NOP */ }
 154 void emit_constraint_double(const char* /*name*/)     { /* NOP */ }
 155 
 156 // CommandLineFlagConstraint emitting code functions if function argument is provided
 157 void emit_constraint_bool(const char* name, CommandLineFlagConstraintFunc_bool func) {
 158   CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_bool(name, func));
 159 }
 160 void emit_constraint_int(const char* name, CommandLineFlagConstraintFunc_int func) {
 161   CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_int(name, func));
 162 }
 163 void emit_constraint_intx(const char* name, CommandLineFlagConstraintFunc_intx func) {
 164   CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_intx(name, func));
 165 }
 166 void emit_constraint_uint(const char* name, CommandLineFlagConstraintFunc_uint func) {
 167   CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint(name, func));
 168 }
 169 void emit_constraint_uintx(const char* name, CommandLineFlagConstraintFunc_uintx func) {
 170   CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uintx(name, func));
 171 }
 172 void emit_constraint_uint64_t(const char* name, CommandLineFlagConstraintFunc_uint64_t func) {
 173   CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint64_t(name, func));
 174 }
 175 void emit_constraint_size_t(const char* name, CommandLineFlagConstraintFunc_size_t func) {
 176   CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_size_t(name, func));
 177 }
 178 void emit_constraint_double(const char* name, CommandLineFlagConstraintFunc_double func) {
 179   CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_double(name, func));
 180 }
 181 
 182 // Generate code to call emit_constraint_xxx function
 183 #define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc)      ); emit_constraint_##type(#name
 184 #define EMIT_CONSTRAINT_COMMERCIAL_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
 185 #define EMIT_CONSTRAINT_DIAGNOSTIC_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
 186 #define EMIT_CONSTRAINT_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_constraint_##type(#name
 187 #define EMIT_CONSTRAINT_MANAGEABLE_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
 188 #define EMIT_CONSTRAINT_PRODUCT_RW_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
 189 #define EMIT_CONSTRAINT_PD_PRODUCT_FLAG(type, name, doc)          ); emit_constraint_##type(#name
 190 #define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc)    ); emit_constraint_##type(#name
 191 #define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_constraint_##type(#name
 192 #define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
 193 #define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name
 194 
 195 // Generate func argument to pass into emit_constraint_xxx functions
 196 #define EMIT_CONSTRAINT_CHECK(func)                               , func
 197 
 198 #define INITIAL_CONTRAINTS_SIZE 16
 199 GrowableArray<CommandLineFlagConstraint*>* CommandLineFlagConstraintList::_constraints = NULL;
 200 
 201 // Check the ranges of all flags that have them or print them out and exit if requested
 202 void CommandLineFlagConstraintList::init(void) {
 203 
 204   _constraints = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagConstraint*>(INITIAL_CONTRAINTS_SIZE, true);
 205 
 206   emit_constraint_no(NULL RUNTIME_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
 207                                         EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
 208                                         EMIT_CONSTRAINT_PRODUCT_FLAG,
 209                                         EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
 210                                         EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
 211                                         EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
 212                                         EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
 213                                         EMIT_CONSTRAINT_MANAGEABLE_FLAG,
 214                                         EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
 215                                         EMIT_CONSTRAINT_LP64_PRODUCT_FLAG,
 216                                         IGNORE_RANGE,
 217                                         EMIT_CONSTRAINT_CHECK));
 218 
 219   EMIT_CONSTRAINTS_FOR_GLOBALS_EXT
 220 
 221   emit_constraint_no(NULL ARCH_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
 222                                      EMIT_CONSTRAINT_PRODUCT_FLAG,
 223                                      EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
 224                                      EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
 225                                      EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
 226                                      IGNORE_RANGE,
 227                                      EMIT_CONSTRAINT_CHECK));
 228 
 229 #ifdef COMPILER1
 230   emit_constraint_no(NULL C1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
 231                                    EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
 232                                    EMIT_CONSTRAINT_PRODUCT_FLAG,
 233                                    EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
 234                                    EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
 235                                    EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
 236                                    IGNORE_RANGE,
 237                                    EMIT_CONSTRAINT_CHECK));
 238 #endif // COMPILER1
 239 
 240 #ifdef COMPILER2
 241   emit_constraint_no(NULL C2_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
 242                                    EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
 243                                    EMIT_CONSTRAINT_PRODUCT_FLAG,
 244                                    EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
 245                                    EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
 246                                    EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
 247                                    EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
 248                                    IGNORE_RANGE,
 249                                    EMIT_CONSTRAINT_CHECK));
 250 #endif // COMPILER2
 251 
 252 #ifndef INCLUDE_ALL_GCS
 253   emit_constraint_no(NULL G1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
 254                                    EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
 255                                    EMIT_CONSTRAINT_PRODUCT_FLAG,
 256                                    EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
 257                                    EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
 258                                    EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
 259                                    EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
 260                                    EMIT_CONSTRAINT_MANAGEABLE_FLAG,
 261                                    EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
 262                                    IGNORE_RANGE,
 263                                    EMIT_CONSTRAINT_CHECK));
 264 #endif // INCLUDE_ALL_GCS
 265 }
 266 
 267 CommandLineFlagConstraint* CommandLineFlagConstraintList::find(const char* name) {
 268   CommandLineFlagConstraint* found = NULL;
 269   for (int i=0; i<length(); i++) {
 270     CommandLineFlagConstraint* constraint = at(i);
 271     if (strcmp(constraint->_name, name) == 0) {
 272       found = constraint;
 273       break;
 274     }
 275   }
 276   return found;
 277 }