1 /*
  2  * Copyright (c) 2015, 2025, 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 "runtime/flags/jvmFlag.hpp"
 26 #include "runtime/flags/jvmFlagLimit.hpp"
 27 #include "runtime/flags/jvmFlagConstraintsRuntime.hpp"
 28 #include "runtime/globals.hpp"
 29 #include "runtime/os.hpp"
 30 #include "runtime/safepointMechanism.hpp"
 31 #include "runtime/task.hpp"
 32 #include "utilities/powerOfTwo.hpp"
 33 
 34 JVMFlag::Error AOTCacheConstraintFunc(ccstr value, bool verbose) {
 35   if (value == nullptr) {
 36     JVMFlag::printError(verbose, "AOTCache cannot be empty\n");
 37     return JVMFlag::VIOLATES_CONSTRAINT;
 38   }
 39   return JVMFlag::SUCCESS;
 40 }
 41 
 42 JVMFlag::Error AOTConfigurationConstraintFunc(ccstr value, bool verbose) {
 43   if (value == nullptr) {
 44     JVMFlag::printError(verbose, "AOTConfiguration cannot be empty\n");
 45     return JVMFlag::VIOLATES_CONSTRAINT;
 46   }
 47   return JVMFlag::SUCCESS;
 48 }
 49 
 50 JVMFlag::Error AOTModeConstraintFunc(ccstr value, bool verbose) {
 51   if (value == nullptr) {
 52     JVMFlag::printError(verbose, "AOTMode cannot be empty\n");
 53     return JVMFlag::VIOLATES_CONSTRAINT;
 54   }
 55   if (strcmp(value, "off") != 0 &&
 56       strcmp(value, "record") != 0 &&
 57       strcmp(value, "create") != 0 &&
 58       strcmp(value, "auto") != 0 &&
 59       strcmp(value, "on") != 0) {
 60     JVMFlag::printError(verbose,
 61                         "Unrecognized value %s for AOTMode. Must be one of the following: "
 62                         "off, record, create, auto, on\n",
 63                         value);
 64     return JVMFlag::VIOLATES_CONSTRAINT;
 65   }
 66   return JVMFlag::SUCCESS;
 67 }
 68 
 69 JVMFlag::Error ObjectAlignmentInBytesConstraintFunc(int value, bool verbose) {
 70   if (!is_power_of_2(value)) {
 71     JVMFlag::printError(verbose,
 72                         "ObjectAlignmentInBytes (%d) must be "
 73                         "power of 2\n",
 74                         value);
 75     return JVMFlag::VIOLATES_CONSTRAINT;
 76   }
 77   // In case page size is very small.
 78   if (value >= (intx)os::vm_page_size()) {
 79     JVMFlag::printError(verbose,
 80                         "ObjectAlignmentInBytes (%d) must be "
 81                         "less than page size (%zu)\n",
 82                         value, os::vm_page_size());
 83     return JVMFlag::VIOLATES_CONSTRAINT;
 84   }
 85   return JVMFlag::SUCCESS;
 86 }
 87 
 88 // Need to enforce the padding not to break the existing field alignments.
 89 // It is sufficient to check against the largest type size.
 90 JVMFlag::Error ContendedPaddingWidthConstraintFunc(int value, bool verbose) {
 91   if ((value % BytesPerLong) != 0) {
 92     JVMFlag::printError(verbose,
 93                         "ContendedPaddingWidth (%d) must be "
 94                         "a multiple of %d\n",
 95                         value, BytesPerLong);
 96     return JVMFlag::VIOLATES_CONSTRAINT;
 97   } else {
 98     return JVMFlag::SUCCESS;
 99   }
100 }
101 
102 JVMFlag::Error PerfDataSamplingIntervalFunc(int value, bool verbose) {
103   if ((value % PeriodicTask::interval_gran != 0)) {
104     JVMFlag::printError(verbose,
105                         "PerfDataSamplingInterval (%d) must be "
106                         "evenly divisible by PeriodicTask::interval_gran (%d)\n",
107                         value, PeriodicTask::interval_gran);
108     return JVMFlag::VIOLATES_CONSTRAINT;
109   } else {
110     return JVMFlag::SUCCESS;
111   }
112 }
113 
114 JVMFlag::Error VMPageSizeConstraintFunc(uintx value, bool verbose) {
115   uintx min = (uintx)os::vm_page_size();
116   if (value < min) {
117     JVMFlag::printError(verbose,
118                         "%s %s=%zu is outside the allowed range [ %zu"
119                         " ... %zu ]\n",
120                         JVMFlagLimit::last_checked_flag()->type_string(),
121                         JVMFlagLimit::last_checked_flag()->name(),
122                         value, min, max_uintx);
123     return JVMFlag::VIOLATES_CONSTRAINT;
124   }
125 
126   return JVMFlag::SUCCESS;
127 }
128 
129 JVMFlag::Error NUMAInterleaveGranularityConstraintFunc(size_t value, bool verbose) {
130   size_t min = os::vm_allocation_granularity();
131   size_t max = NOT_LP64(2*G) LP64_ONLY(8192*G);
132 
133   if (value < min || value > max) {
134     JVMFlag::printError(verbose,
135                         "size_t NUMAInterleaveGranularity=%zu is outside the allowed range [ %zu"
136                         " ... %zu ]\n", value, min, max);
137     return JVMFlag::VIOLATES_CONSTRAINT;
138   }
139 
140   return JVMFlag::SUCCESS;
141 }
142 
143 JVMFlag::Error OnSpinWaitInstNameConstraintFunc(ccstr value, bool verbose) {
144 #ifdef AARCH64
145   if (value == nullptr) {
146     JVMFlag::printError(verbose, "OnSpinWaitInst cannot be empty\n");
147     return JVMFlag::VIOLATES_CONSTRAINT;
148   }
149 
150   if (strcmp(value, "nop")   != 0 &&
151       strcmp(value, "isb")   != 0 &&
152       strcmp(value, "yield") != 0 &&
153       strcmp(value, "sb")    != 0 &&
154       strcmp(value, "none")  != 0) {
155     JVMFlag::printError(verbose,
156                         "Unrecognized value %s for OnSpinWaitInst. Must be one of the following: "
157                         "nop, isb, yield, sb, none\n",
158                         value);
159     return JVMFlag::VIOLATES_CONSTRAINT;
160   }
161 #endif
162   return JVMFlag::SUCCESS;
163 }