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