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