8081833: Clean up JVMFlag getter/setter code

Reviewed-by: gziemski, coleenp
This commit is contained in:
Ioi Lam 2020-09-22 06:04:31 +00:00
parent 0e98fc1ccd
commit 282b9dcfdc
26 changed files with 888 additions and 1607 deletions

View file

@ -279,11 +279,11 @@ TRACE_REQUEST_FUNC(ThreadContextSwitchRate) {
#define SEND_FLAGS_OF_TYPE(eventType, flagType) \ #define SEND_FLAGS_OF_TYPE(eventType, flagType) \
do { \ do { \
JVMFlag *flag = JVMFlag::flags; \ JVMFlag *flag = JVMFlag::flags; \
while (flag->_name != NULL) { \ while (flag->name() != NULL) { \
if (flag->is_ ## flagType()) { \ if (flag->is_ ## flagType()) { \
if (flag->is_unlocked()) { \ if (flag->is_unlocked()) { \
Event ## eventType event; \ Event ## eventType event; \
event.set_name(flag->_name); \ event.set_name(flag->name()); \
event.set_value(flag->get_ ## flagType()); \ event.set_value(flag->get_ ## flagType()); \
event.set_origin(flag->get_origin()); \ event.set_origin(flag->get_origin()); \
event.commit(); \ event.commit(); \

View file

@ -237,7 +237,7 @@ C2V_VMENTRY_NULL(jobject, getFlagValue, (JNIEnv* env, jobject c2vm, jobject name
} else if (flag->is_double()) { } else if (flag->is_double()) {
RETURN_BOXED_DOUBLE(flag->get_double()); RETURN_BOXED_DOUBLE(flag->get_double());
} else { } else {
JVMCI_ERROR_NULL("VM flag %s has unsupported type %s", flag->_name, flag->_type); JVMCI_ERROR_NULL("VM flag %s has unsupported type %s", flag->name(), flag->type_string());
} }
#undef RETURN_BOXED_LONG #undef RETURN_BOXED_LONG
#undef RETURN_BOXED_DOUBLE #undef RETURN_BOXED_DOUBLE

View file

@ -23,13 +23,14 @@
*/ */
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc/shared/gcConfig.hpp"
#include "jvm.h" #include "jvm.h"
#include "jvmci/jvmci_globals.hpp" #include "jvmci/jvmci_globals.hpp"
#include "gc/shared/gcConfig.hpp" #include "runtime/arguments.hpp"
#include "runtime/flags/jvmFlagAccess.hpp"
#include "runtime/globals_extension.hpp"
#include "utilities/defaultStream.hpp" #include "utilities/defaultStream.hpp"
#include "utilities/ostream.hpp" #include "utilities/ostream.hpp"
#include "runtime/arguments.hpp"
#include "runtime/globals_extension.hpp"
fileStream* JVMCIGlobals::_jni_config_file = NULL; fileStream* JVMCIGlobals::_jni_config_file = NULL;
@ -187,7 +188,7 @@ bool JVMCIGlobals::enable_jvmci_product_mode(JVMFlag::Flags origin) {
bool value = true; bool value = true;
JVMFlag *jvmciEnableFlag = JVMFlag::find_flag("EnableJVMCIProduct"); JVMFlag *jvmciEnableFlag = JVMFlag::find_flag("EnableJVMCIProduct");
if (JVMFlag::boolAtPut(jvmciEnableFlag, &value, origin) != JVMFlag::SUCCESS) { if (JVMFlagAccess::boolAtPut(jvmciEnableFlag, &value, origin) != JVMFlag::SUCCESS) {
return false; return false;
} }

View file

@ -59,7 +59,7 @@
#include "prims/resolvedMethodTable.hpp" #include "prims/resolvedMethodTable.hpp"
#include "runtime/arguments.hpp" #include "runtime/arguments.hpp"
#include "runtime/atomic.hpp" #include "runtime/atomic.hpp"
#include "runtime/flags/jvmFlagConstraintList.hpp" #include "runtime/flags/jvmFlagLimit.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
#include "runtime/init.hpp" #include "runtime/init.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
@ -753,7 +753,7 @@ jint universe_init() {
AOTLoader::universe_init(); AOTLoader::universe_init();
// Checks 'AfterMemoryInit' constraints. // Checks 'AfterMemoryInit' constraints.
if (!JVMFlagConstraintList::check_constraints(JVMFlagConstraint::AfterMemoryInit)) { if (!JVMFlagLimit::check_all_constraints(JVMFlagConstraintPhase::AfterMemoryInit)) {
return JNI_EINVAL; return JNI_EINVAL;
} }

View file

@ -66,6 +66,7 @@
#include "runtime/deoptimization.hpp" #include "runtime/deoptimization.hpp"
#include "runtime/fieldDescriptor.inline.hpp" #include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/flags/jvmFlag.hpp" #include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagAccess.hpp"
#include "runtime/frame.inline.hpp" #include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
#include "runtime/handshake.hpp" #include "runtime/handshake.hpp"
@ -1205,8 +1206,8 @@ WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
} }
WB_END WB_END
template <typename T> template <typename T, int type_enum>
static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, JVMFlag::Error (*TAt)(const JVMFlag*, T*)) { static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value) {
if (name == NULL) { if (name == NULL) {
return false; return false;
} }
@ -1214,13 +1215,13 @@ static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, J
const char* flag_name = env->GetStringUTFChars(name, NULL); const char* flag_name = env->GetStringUTFChars(name, NULL);
CHECK_JNI_EXCEPTION_(env, false); CHECK_JNI_EXCEPTION_(env, false);
const JVMFlag* flag = JVMFlag::find_declared_flag(flag_name); const JVMFlag* flag = JVMFlag::find_declared_flag(flag_name);
JVMFlag::Error result = (*TAt)(flag, value); JVMFlag::Error result = JVMFlagAccess::get<T, type_enum>(flag, value);
env->ReleaseStringUTFChars(name, flag_name); env->ReleaseStringUTFChars(name, flag_name);
return (result == JVMFlag::SUCCESS); return (result == JVMFlag::SUCCESS);
} }
template <typename T> template <typename T, int type_enum>
static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, JVMFlag::Error (*TAtPut)(JVMFlag* flag, T*, JVMFlag::Flags)) { static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value) {
if (name == NULL) { if (name == NULL) {
return false; return false;
} }
@ -1228,7 +1229,7 @@ static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, J
const char* flag_name = env->GetStringUTFChars(name, NULL); const char* flag_name = env->GetStringUTFChars(name, NULL);
CHECK_JNI_EXCEPTION_(env, false); CHECK_JNI_EXCEPTION_(env, false);
JVMFlag* flag = JVMFlag::find_flag(flag_name); JVMFlag* flag = JVMFlag::find_flag(flag_name);
JVMFlag::Error result = (*TAtPut)(flag, value, JVMFlag::INTERNAL); JVMFlag::Error result = JVMFlagAccess::set<T, type_enum>(flag, value, JVMFlag::INTERNAL);
env->ReleaseStringUTFChars(name, flag_name); env->ReleaseStringUTFChars(name, flag_name);
return (result == JVMFlag::SUCCESS); return (result == JVMFlag::SUCCESS);
} }
@ -1284,7 +1285,7 @@ WB_END
WB_ENTRY(jobject, WB_GetBooleanVMFlag(JNIEnv* env, jobject o, jstring name)) WB_ENTRY(jobject, WB_GetBooleanVMFlag(JNIEnv* env, jobject o, jstring name))
bool result; bool result;
if (GetVMFlag <bool> (thread, env, name, &result, &JVMFlag::boolAt)) { if (GetVMFlag <JVM_FLAG_TYPE(bool)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return booleanBox(thread, env, result); return booleanBox(thread, env, result);
} }
@ -1293,7 +1294,7 @@ WB_END
WB_ENTRY(jobject, WB_GetIntVMFlag(JNIEnv* env, jobject o, jstring name)) WB_ENTRY(jobject, WB_GetIntVMFlag(JNIEnv* env, jobject o, jstring name))
int result; int result;
if (GetVMFlag <int> (thread, env, name, &result, &JVMFlag::intAt)) { if (GetVMFlag <JVM_FLAG_TYPE(int)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result); return longBox(thread, env, result);
} }
@ -1302,7 +1303,7 @@ WB_END
WB_ENTRY(jobject, WB_GetUintVMFlag(JNIEnv* env, jobject o, jstring name)) WB_ENTRY(jobject, WB_GetUintVMFlag(JNIEnv* env, jobject o, jstring name))
uint result; uint result;
if (GetVMFlag <uint> (thread, env, name, &result, &JVMFlag::uintAt)) { if (GetVMFlag <JVM_FLAG_TYPE(uint)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result); return longBox(thread, env, result);
} }
@ -1311,7 +1312,7 @@ WB_END
WB_ENTRY(jobject, WB_GetIntxVMFlag(JNIEnv* env, jobject o, jstring name)) WB_ENTRY(jobject, WB_GetIntxVMFlag(JNIEnv* env, jobject o, jstring name))
intx result; intx result;
if (GetVMFlag <intx> (thread, env, name, &result, &JVMFlag::intxAt)) { if (GetVMFlag <JVM_FLAG_TYPE(intx)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result); return longBox(thread, env, result);
} }
@ -1320,7 +1321,7 @@ WB_END
WB_ENTRY(jobject, WB_GetUintxVMFlag(JNIEnv* env, jobject o, jstring name)) WB_ENTRY(jobject, WB_GetUintxVMFlag(JNIEnv* env, jobject o, jstring name))
uintx result; uintx result;
if (GetVMFlag <uintx> (thread, env, name, &result, &JVMFlag::uintxAt)) { if (GetVMFlag <JVM_FLAG_TYPE(uintx)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result); return longBox(thread, env, result);
} }
@ -1329,7 +1330,7 @@ WB_END
WB_ENTRY(jobject, WB_GetUint64VMFlag(JNIEnv* env, jobject o, jstring name)) WB_ENTRY(jobject, WB_GetUint64VMFlag(JNIEnv* env, jobject o, jstring name))
uint64_t result; uint64_t result;
if (GetVMFlag <uint64_t> (thread, env, name, &result, &JVMFlag::uint64_tAt)) { if (GetVMFlag <JVM_FLAG_TYPE(uint64_t)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result); return longBox(thread, env, result);
} }
@ -1338,7 +1339,7 @@ WB_END
WB_ENTRY(jobject, WB_GetSizeTVMFlag(JNIEnv* env, jobject o, jstring name)) WB_ENTRY(jobject, WB_GetSizeTVMFlag(JNIEnv* env, jobject o, jstring name))
size_t result; size_t result;
if (GetVMFlag <size_t> (thread, env, name, &result, &JVMFlag::size_tAt)) { if (GetVMFlag <JVM_FLAG_TYPE(size_t)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result); return longBox(thread, env, result);
} }
@ -1347,7 +1348,7 @@ WB_END
WB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name)) WB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name))
double result; double result;
if (GetVMFlag <double> (thread, env, name, &result, &JVMFlag::doubleAt)) { if (GetVMFlag <JVM_FLAG_TYPE(double)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return doubleBox(thread, env, result); return doubleBox(thread, env, result);
} }
@ -1356,7 +1357,7 @@ WB_END
WB_ENTRY(jstring, WB_GetStringVMFlag(JNIEnv* env, jobject o, jstring name)) WB_ENTRY(jstring, WB_GetStringVMFlag(JNIEnv* env, jobject o, jstring name))
ccstr ccstrResult; ccstr ccstrResult;
if (GetVMFlag <ccstr> (thread, env, name, &ccstrResult, &JVMFlag::ccstrAt)) { if (GetVMFlag <JVM_FLAG_TYPE(ccstr)> (thread, env, name, &ccstrResult)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
jstring result = env->NewStringUTF(ccstrResult); jstring result = env->NewStringUTF(ccstrResult);
CHECK_JNI_EXCEPTION_(env, NULL); CHECK_JNI_EXCEPTION_(env, NULL);
@ -1367,42 +1368,42 @@ WB_END
WB_ENTRY(void, WB_SetBooleanVMFlag(JNIEnv* env, jobject o, jstring name, jboolean value)) WB_ENTRY(void, WB_SetBooleanVMFlag(JNIEnv* env, jobject o, jstring name, jboolean value))
bool result = value == JNI_TRUE ? true : false; bool result = value == JNI_TRUE ? true : false;
SetVMFlag <bool> (thread, env, name, &result, &JVMFlag::boolAtPut); SetVMFlag <JVM_FLAG_TYPE(bool)> (thread, env, name, &result);
WB_END WB_END
WB_ENTRY(void, WB_SetIntVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) WB_ENTRY(void, WB_SetIntVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
int result = value; int result = value;
SetVMFlag <int> (thread, env, name, &result, &JVMFlag::intAtPut); SetVMFlag <JVM_FLAG_TYPE(int)> (thread, env, name, &result);
WB_END WB_END
WB_ENTRY(void, WB_SetUintVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) WB_ENTRY(void, WB_SetUintVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
uint result = value; uint result = value;
SetVMFlag <uint> (thread, env, name, &result, &JVMFlag::uintAtPut); SetVMFlag <JVM_FLAG_TYPE(uint)> (thread, env, name, &result);
WB_END WB_END
WB_ENTRY(void, WB_SetIntxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) WB_ENTRY(void, WB_SetIntxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
intx result = value; intx result = value;
SetVMFlag <intx> (thread, env, name, &result, &JVMFlag::intxAtPut); SetVMFlag <JVM_FLAG_TYPE(intx)> (thread, env, name, &result);
WB_END WB_END
WB_ENTRY(void, WB_SetUintxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) WB_ENTRY(void, WB_SetUintxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
uintx result = value; uintx result = value;
SetVMFlag <uintx> (thread, env, name, &result, &JVMFlag::uintxAtPut); SetVMFlag <JVM_FLAG_TYPE(uintx)> (thread, env, name, &result);
WB_END WB_END
WB_ENTRY(void, WB_SetUint64VMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) WB_ENTRY(void, WB_SetUint64VMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
uint64_t result = value; uint64_t result = value;
SetVMFlag <uint64_t> (thread, env, name, &result, &JVMFlag::uint64_tAtPut); SetVMFlag <JVM_FLAG_TYPE(uint64_t)> (thread, env, name, &result);
WB_END WB_END
WB_ENTRY(void, WB_SetSizeTVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) WB_ENTRY(void, WB_SetSizeTVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
size_t result = value; size_t result = value;
SetVMFlag <size_t> (thread, env, name, &result, &JVMFlag::size_tAtPut); SetVMFlag <JVM_FLAG_TYPE(size_t)> (thread, env, name, &result);
WB_END WB_END
WB_ENTRY(void, WB_SetDoubleVMFlag(JNIEnv* env, jobject o, jstring name, jdouble value)) WB_ENTRY(void, WB_SetDoubleVMFlag(JNIEnv* env, jobject o, jstring name, jdouble value))
double result = value; double result = value;
SetVMFlag <double> (thread, env, name, &result, &JVMFlag::doubleAtPut); SetVMFlag <JVM_FLAG_TYPE(double)> (thread, env, name, &result);
WB_END WB_END
WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value)) WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value))
@ -1419,7 +1420,7 @@ WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring
bool needFree; bool needFree;
{ {
ThreadInVMfromNative ttvfn(thread); // back to VM ThreadInVMfromNative ttvfn(thread); // back to VM
needFree = SetVMFlag <ccstr> (thread, env, name, &ccstrResult, &JVMFlag::ccstrAtPut); needFree = SetVMFlag <JVM_FLAG_TYPE(ccstr)> (thread, env, name, &ccstrResult);
} }
if (value != NULL) { if (value != NULL) {
env->ReleaseStringUTFChars(value, ccstrValue); env->ReleaseStringUTFChars(value, ccstrValue);

View file

@ -41,8 +41,7 @@
#include "prims/jvmtiExport.hpp" #include "prims/jvmtiExport.hpp"
#include "runtime/arguments.hpp" #include "runtime/arguments.hpp"
#include "runtime/flags/jvmFlag.hpp" #include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagConstraintList.hpp" #include "runtime/flags/jvmFlagAccess.hpp"
#include "runtime/flags/jvmFlagRangeList.hpp"
#include "runtime/globals_extension.hpp" #include "runtime/globals_extension.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
#include "runtime/os.inline.hpp" #include "runtime/os.inline.hpp"
@ -877,7 +876,7 @@ void Arguments::describe_range_error(ArgsRange errcode) {
} }
static bool set_bool_flag(JVMFlag* flag, bool value, JVMFlag::Flags origin) { static bool set_bool_flag(JVMFlag* flag, bool value, JVMFlag::Flags origin) {
if (JVMFlag::boolAtPut(flag, &value, origin) == JVMFlag::SUCCESS) { if (JVMFlagAccess::boolAtPut(flag, &value, origin) == JVMFlag::SUCCESS) {
return true; return true;
} else { } else {
return false; return false;
@ -892,7 +891,7 @@ static bool set_fp_numeric_flag(JVMFlag* flag, char* value, JVMFlag::Flags origi
return false; return false;
} }
if (JVMFlag::doubleAtPut(flag, &v, origin) == JVMFlag::SUCCESS) { if (JVMFlagAccess::doubleAtPut(flag, &v, origin) == JVMFlag::SUCCESS) {
return true; return true;
} }
return false; return false;
@ -924,35 +923,35 @@ static bool set_numeric_flag(JVMFlag* flag, char* value, JVMFlag::Flags origin)
if (is_neg) { if (is_neg) {
int_v = -int_v; int_v = -int_v;
} }
return JVMFlag::intAtPut(flag, &int_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::intAtPut(flag, &int_v, origin) == JVMFlag::SUCCESS;
} else if (flag->is_uint()) { } else if (flag->is_uint()) {
uint uint_v = (uint) v; uint uint_v = (uint) v;
return JVMFlag::uintAtPut(flag, &uint_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::uintAtPut(flag, &uint_v, origin) == JVMFlag::SUCCESS;
} else if (flag->is_intx()) { } else if (flag->is_intx()) {
intx_v = (intx) v; intx_v = (intx) v;
if (is_neg) { if (is_neg) {
intx_v = -intx_v; intx_v = -intx_v;
} }
return JVMFlag::intxAtPut(flag, &intx_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::intxAtPut(flag, &intx_v, origin) == JVMFlag::SUCCESS;
} else if (flag->is_uintx()) { } else if (flag->is_uintx()) {
uintx uintx_v = (uintx) v; uintx uintx_v = (uintx) v;
return JVMFlag::uintxAtPut(flag, &uintx_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::uintxAtPut(flag, &uintx_v, origin) == JVMFlag::SUCCESS;
} else if (flag->is_uint64_t()) { } else if (flag->is_uint64_t()) {
uint64_t uint64_t_v = (uint64_t) v; uint64_t uint64_t_v = (uint64_t) v;
return JVMFlag::uint64_tAtPut(flag, &uint64_t_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::uint64_tAtPut(flag, &uint64_t_v, origin) == JVMFlag::SUCCESS;
} else if (flag->is_size_t()) { } else if (flag->is_size_t()) {
size_t size_t_v = (size_t) v; size_t size_t_v = (size_t) v;
return JVMFlag::size_tAtPut(flag, &size_t_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::size_tAtPut(flag, &size_t_v, origin) == JVMFlag::SUCCESS;
} else if (flag->is_double()) { } else if (flag->is_double()) {
double double_v = (double) v; double double_v = (double) v;
return JVMFlag::doubleAtPut(flag, &double_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::doubleAtPut(flag, &double_v, origin) == JVMFlag::SUCCESS;
} else { } else {
return false; return false;
} }
} }
static bool set_string_flag(JVMFlag* flag, const char* value, JVMFlag::Flags origin) { static bool set_string_flag(JVMFlag* flag, const char* value, JVMFlag::Flags origin) {
if (JVMFlag::ccstrAtPut(flag, &value, origin) != JVMFlag::SUCCESS) return false; if (JVMFlagAccess::ccstrAtPut(flag, &value, origin) != JVMFlag::SUCCESS) return false;
// Contract: JVMFlag always returns a pointer that needs freeing. // Contract: JVMFlag always returns a pointer that needs freeing.
FREE_C_HEAP_ARRAY(char, value); FREE_C_HEAP_ARRAY(char, value);
return true; return true;
@ -960,7 +959,7 @@ static bool set_string_flag(JVMFlag* flag, const char* value, JVMFlag::Flags ori
static bool append_to_string_flag(JVMFlag* flag, const char* new_value, JVMFlag::Flags origin) { static bool append_to_string_flag(JVMFlag* flag, const char* new_value, JVMFlag::Flags origin) {
const char* old_value = ""; const char* old_value = "";
if (JVMFlag::ccstrAt(flag, &old_value) != JVMFlag::SUCCESS) return false; if (JVMFlagAccess::ccstrAt(flag, &old_value) != JVMFlag::SUCCESS) return false;
size_t old_len = old_value != NULL ? strlen(old_value) : 0; size_t old_len = old_value != NULL ? strlen(old_value) : 0;
size_t new_len = strlen(new_value); size_t new_len = strlen(new_value);
const char* value; const char* value;
@ -977,7 +976,7 @@ static bool append_to_string_flag(JVMFlag* flag, const char* new_value, JVMFlag:
value = buf; value = buf;
free_this_too = buf; free_this_too = buf;
} }
(void) JVMFlag::ccstrAtPut(flag, &value, origin); (void) JVMFlagAccess::ccstrAtPut(flag, &value, origin);
// JVMFlag always returns a pointer that needs freeing. // JVMFlag always returns a pointer that needs freeing.
FREE_C_HEAP_ARRAY(char, value); FREE_C_HEAP_ARRAY(char, value);
// JVMFlag made its own copy, so I must delete my own temp. buffer. // JVMFlag made its own copy, so I must delete my own temp. buffer.
@ -1355,7 +1354,7 @@ bool Arguments::process_argument(const char* arg,
jio_fprintf(defaultStream::error_stream(), jio_fprintf(defaultStream::error_stream(),
"Did you mean '%s%s%s'? ", "Did you mean '%s%s%s'? ",
(fuzzy_matched->is_bool()) ? "(+/-)" : "", (fuzzy_matched->is_bool()) ? "(+/-)" : "",
fuzzy_matched->_name, fuzzy_matched->name(),
(fuzzy_matched->is_bool()) ? "" : "=<value>"); (fuzzy_matched->is_bool()) ? "" : "=<value>");
} }
} }

View file

@ -27,63 +27,12 @@
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "runtime/arguments.hpp" #include "runtime/arguments.hpp"
#include "runtime/flags/jvmFlag.hpp" #include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagConstraintList.hpp" #include "runtime/flags/jvmFlagAccess.hpp"
#include "runtime/flags/jvmFlagLookup.hpp" #include "runtime/flags/jvmFlagLookup.hpp"
#include "runtime/flags/jvmFlagRangeList.hpp"
#include "runtime/globals_extension.hpp" #include "runtime/globals_extension.hpp"
#include "utilities/defaultStream.hpp" #include "utilities/defaultStream.hpp"
#include "utilities/stringUtils.hpp" #include "utilities/stringUtils.hpp"
#define DEFAULT_RANGE_STR_CHUNK_SIZE 64
static char* create_range_str(const char *fmt, ...) {
static size_t string_length = DEFAULT_RANGE_STR_CHUNK_SIZE;
static char* range_string = NEW_C_HEAP_ARRAY(char, string_length, mtLogging);
int size_needed = 0;
do {
va_list args;
va_start(args, fmt);
size_needed = jio_vsnprintf(range_string, string_length, fmt, args);
va_end(args);
if (size_needed < 0) {
string_length += DEFAULT_RANGE_STR_CHUNK_SIZE;
range_string = REALLOC_C_HEAP_ARRAY(char, range_string, string_length, mtLogging);
guarantee(range_string != NULL, "create_range_str string should not be NULL");
}
} while (size_needed < 0);
return range_string;
}
const char* JVMFlag::get_int_default_range_str() {
return create_range_str("[ " INT32_FORMAT_W(-25) " ... " INT32_FORMAT_W(25) " ]", INT_MIN, INT_MAX);
}
const char* JVMFlag::get_uint_default_range_str() {
return create_range_str("[ " UINT32_FORMAT_W(-25) " ... " UINT32_FORMAT_W(25) " ]", 0, UINT_MAX);
}
const char* JVMFlag::get_intx_default_range_str() {
return create_range_str("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", min_intx, max_intx);
}
const char* JVMFlag::get_uintx_default_range_str() {
return create_range_str("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", 0, max_uintx);
}
const char* JVMFlag::get_uint64_t_default_range_str() {
return create_range_str("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", 0, uint64_t(max_juint));
}
const char* JVMFlag::get_size_t_default_range_str() {
return create_range_str("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", 0, SIZE_MAX);
}
const char* JVMFlag::get_double_default_range_str() {
return create_range_str("[ %-25.3f ... %25.3f ]", DBL_MIN, DBL_MAX);
}
static bool is_product_build() { static bool is_product_build() {
#ifdef PRODUCT #ifdef PRODUCT
return true; return true;
@ -92,100 +41,12 @@ static bool is_product_build() {
#endif #endif
} }
bool JVMFlag::is_bool() const {
return strcmp(_type, "bool") == 0;
}
bool JVMFlag::is_int() const {
return strcmp(_type, "int") == 0;
}
bool JVMFlag::is_uint() const {
return strcmp(_type, "uint") == 0;
}
bool JVMFlag::is_intx() const {
return strcmp(_type, "intx") == 0;
}
bool JVMFlag::is_uintx() const {
return strcmp(_type, "uintx") == 0;
}
bool JVMFlag::is_uint64_t() const {
return strcmp(_type, "uint64_t") == 0;
}
bool JVMFlag::is_size_t() const {
return strcmp(_type, "size_t") == 0;
}
bool JVMFlag::is_double() const {
return strcmp(_type, "double") == 0;
}
bool JVMFlag::is_ccstr() const {
return strcmp(_type, "ccstr") == 0 || strcmp(_type, "ccstrlist") == 0;
}
bool JVMFlag::ccstr_accumulates() const {
return strcmp(_type, "ccstrlist") == 0;
}
JVMFlag::Flags JVMFlag::get_origin() const {
return Flags(_flags & VALUE_ORIGIN_MASK);
}
void JVMFlag::set_origin(Flags origin) { void JVMFlag::set_origin(Flags origin) {
assert((origin & VALUE_ORIGIN_MASK) == origin, "sanity"); assert((origin & VALUE_ORIGIN_MASK) == origin, "sanity");
Flags new_origin = Flags((origin == COMMAND_LINE) ? Flags(origin | ORIG_COMMAND_LINE) : origin); Flags new_origin = Flags((origin == COMMAND_LINE) ? Flags(origin | ORIG_COMMAND_LINE) : origin);
_flags = Flags((_flags & ~VALUE_ORIGIN_MASK) | new_origin); _flags = Flags((_flags & ~VALUE_ORIGIN_MASK) | new_origin);
} }
bool JVMFlag::is_default() const {
return (get_origin() == DEFAULT);
}
bool JVMFlag::is_ergonomic() const {
return (get_origin() == ERGONOMIC);
}
bool JVMFlag::is_command_line() const {
return (_flags & ORIG_COMMAND_LINE) != 0;
}
bool JVMFlag::is_jimage_resource() const {
return (get_origin() == JIMAGE_RESOURCE);
}
void JVMFlag::set_command_line() {
_flags = Flags(_flags | ORIG_COMMAND_LINE);
}
bool JVMFlag::is_product() const {
return (_flags & KIND_PRODUCT) != 0;
}
bool JVMFlag::is_manageable() const {
return (_flags & KIND_MANAGEABLE) != 0;
}
bool JVMFlag::is_diagnostic() const {
return (_flags & KIND_DIAGNOSTIC) != 0;
}
bool JVMFlag::is_experimental() const {
return (_flags & KIND_EXPERIMENTAL) != 0;
}
bool JVMFlag::is_notproduct() const {
return (_flags & KIND_NOT_PRODUCT) != 0;
}
bool JVMFlag::is_develop() const {
return (_flags & KIND_DEVELOP) != 0;
}
/** /**
* Returns if this flag is a constant in the binary. Right now this is * Returns if this flag is a constant in the binary. Right now this is
* true for notproduct and develop flags in product builds. * true for notproduct and develop flags in product builds.
@ -262,17 +123,6 @@ JVMFlag::MsgType JVMFlag::get_locked_message(char* buf, int buflen) const {
return JVMFlag::NONE; return JVMFlag::NONE;
} }
bool JVMFlag::is_writeable() const {
return is_manageable();
}
// All flags except "manageable" are assumed to be internal flags.
// Long term, we need to define a mechanism to specify which flags
// are external/stable and change this function accordingly.
bool JVMFlag::is_external() const {
return is_manageable();
}
// Helper function for JVMFlag::print_on(). // Helper function for JVMFlag::print_on().
// Fills current line up to requested position. // Fills current line up to requested position.
// Should the current position already be past the requested position, // Should the current position already be past the requested position,
@ -341,7 +191,7 @@ void JVMFlag::print_on(outputStream* st, bool withComments, bool printRanges) co
const unsigned int col7_width = 1; const unsigned int col7_width = 1;
st->fill_to(col1_pos); st->fill_to(col1_pos);
st->print("%*s", col1_width, _type); // right-justified, therefore width is required. st->print("%*s", col1_width, type_string()); // right-justified, therefore width is required.
fill_to_pos(st, col2_pos); fill_to_pos(st, col2_pos);
st->print("%s", _name); st->print("%s", _name);
@ -385,7 +235,7 @@ void JVMFlag::print_on(outputStream* st, bool withComments, bool printRanges) co
st->print("%s", cp); st->print("%s", cp);
} }
} else { } else {
st->print("unhandled type %s", _type); st->print("unhandled type %s", type_string());
st->cr(); st->cr();
return; return;
} }
@ -449,33 +299,13 @@ void JVMFlag::print_on(outputStream* st, bool withComments, bool printRanges) co
const unsigned int col7_width = 1; const unsigned int col7_width = 1;
st->fill_to(col1_pos); st->fill_to(col1_pos);
st->print("%*s", col1_width, _type); // right-justified, therefore width is required. st->print("%*s", col1_width, type_string()); // right-justified, therefore width is required.
fill_to_pos(st, col2_pos); fill_to_pos(st, col2_pos);
st->print("%s", _name); st->print("%s", _name);
fill_to_pos(st, col4_pos); fill_to_pos(st, col4_pos);
RangeStrFunc func = NULL; JVMFlagAccess::print_range(st, this);
if (is_int()) {
func = JVMFlag::get_int_default_range_str;
} else if (is_uint()) {
func = JVMFlag::get_uint_default_range_str;
} else if (is_intx()) {
func = JVMFlag::get_intx_default_range_str;
} else if (is_uintx()) {
func = JVMFlag::get_uintx_default_range_str;
} else if (is_uint64_t()) {
func = JVMFlag::get_uint64_t_default_range_str;
} else if (is_size_t()) {
func = JVMFlag::get_size_t_default_range_str;
} else if (is_double()) {
func = JVMFlag::get_double_default_range_str;
} else {
st->print("unhandled type %s", _type);
st->cr();
return;
}
JVMFlagRangeList::print(st, this, func);
fill_to_pos(st, col5_pos); fill_to_pos(st, col5_pos);
print_kind(st, col5_width); print_kind(st, col5_width);
@ -662,9 +492,9 @@ static constexpr int flag_group(int flag_enum) {
return 0; return 0;
} }
constexpr JVMFlag::JVMFlag(int flag_enum, const char* type, const char* name, constexpr JVMFlag::JVMFlag(int flag_enum, FlagType type, const char* name,
void* addr, int flags, int extra_flags, const char* doc) : void* addr, int flags, int extra_flags, const char* doc) :
_type(type), _name(name), _addr(addr), _flags() NOT_PRODUCT(COMMA _doc(doc)) { _addr(addr), _name(name), _flags(), _type(type) NOT_PRODUCT(COMMA _doc(doc)) {
flags = flags | extra_flags | JVMFlag::DEFAULT | flag_group(flag_enum); flags = flags | extra_flags | JVMFlag::DEFAULT | flag_group(flag_enum);
if ((flags & JVMFlag::KIND_PRODUCT) != 0) { if ((flags & JVMFlag::KIND_PRODUCT) != 0) {
if (flags & (JVMFlag::KIND_DIAGNOSTIC | JVMFlag::KIND_MANAGEABLE | JVMFlag::KIND_EXPERIMENTAL)) { if (flags & (JVMFlag::KIND_DIAGNOSTIC | JVMFlag::KIND_MANAGEABLE | JVMFlag::KIND_EXPERIMENTAL)) {
@ -675,7 +505,7 @@ constexpr JVMFlag::JVMFlag(int flag_enum, const char* type, const char* name,
_flags = static_cast<Flags>(flags); _flags = static_cast<Flags>(flags);
} }
constexpr JVMFlag::JVMFlag(int flag_enum, const char* type, const char* name, constexpr JVMFlag::JVMFlag(int flag_enum, FlagType type, const char* name,
void* addr, int flags, const char* doc) : void* addr, int flags, const char* doc) :
JVMFlag(flag_enum, type, name, addr, flags, /*extra_flags*/0, doc) {} JVMFlag(flag_enum, type, name, addr, flags, /*extra_flags*/0, doc) {}
@ -685,11 +515,12 @@ const int DEVELOP_KIND = JVMFlag::KIND_DEVELOP;
const int DEVELOP_KIND_PD = JVMFlag::KIND_DEVELOP | JVMFlag::KIND_PLATFORM_DEPENDENT; const int DEVELOP_KIND_PD = JVMFlag::KIND_DEVELOP | JVMFlag::KIND_PLATFORM_DEPENDENT;
const int NOTPROD_KIND = JVMFlag::KIND_NOT_PRODUCT; const int NOTPROD_KIND = JVMFlag::KIND_NOT_PRODUCT;
#define DEVELOP_FLAG_INIT( type, name, value, ...) JVMFlag(FLAG_MEMBER_ENUM(name), #type, XSTR(name), (void*)&name, DEVELOP_KIND, __VA_ARGS__), #define FLAG_TYPE(type) (JVMFlag::TYPE_ ## type)
#define DEVELOP_FLAG_INIT_PD(type, name, ...) JVMFlag(FLAG_MEMBER_ENUM(name), #type, XSTR(name), (void*)&name, DEVELOP_KIND_PD, __VA_ARGS__), #define INITIALIZE_DEVELOP_FLAG( type, name, value, ...) JVMFlag(FLAG_MEMBER_ENUM(name), FLAG_TYPE(type), XSTR(name), (void*)&name, DEVELOP_KIND, __VA_ARGS__),
#define PRODUCT_FLAG_INIT( type, name, value, ...) JVMFlag(FLAG_MEMBER_ENUM(name), #type, XSTR(name), (void*)&name, PRODUCT_KIND, __VA_ARGS__), #define INITIALIZE_DEVELOP_FLAG_PD(type, name, ...) JVMFlag(FLAG_MEMBER_ENUM(name), FLAG_TYPE(type), XSTR(name), (void*)&name, DEVELOP_KIND_PD, __VA_ARGS__),
#define PRODUCT_FLAG_INIT_PD(type, name, ...) JVMFlag(FLAG_MEMBER_ENUM(name), #type, XSTR(name), (void*)&name, PRODUCT_KIND_PD, __VA_ARGS__), #define INITIALIZE_PRODUCT_FLAG( type, name, value, ...) JVMFlag(FLAG_MEMBER_ENUM(name), FLAG_TYPE(type), XSTR(name), (void*)&name, PRODUCT_KIND, __VA_ARGS__),
#define NOTPROD_FLAG_INIT( type, name, value, ...) JVMFlag(FLAG_MEMBER_ENUM(name), #type, XSTR(name), (void*)&name, NOTPROD_KIND, __VA_ARGS__), #define INITIALIZE_PRODUCT_FLAG_PD(type, name, ...) JVMFlag(FLAG_MEMBER_ENUM(name), FLAG_TYPE(type), XSTR(name), (void*)&name, PRODUCT_KIND_PD, __VA_ARGS__),
#define INITIALIZE_NOTPROD_FLAG( type, name, value, ...) JVMFlag(FLAG_MEMBER_ENUM(name), FLAG_TYPE(type), XSTR(name), (void*)&name, NOTPROD_KIND, __VA_ARGS__),
// Handy aliases to match the symbols used in the flag specification macros. // Handy aliases to match the symbols used in the flag specification macros.
const int DIAGNOSTIC = JVMFlag::KIND_DIAGNOSTIC; const int DIAGNOSTIC = JVMFlag::KIND_DIAGNOSTIC;
@ -697,11 +528,11 @@ const int MANAGEABLE = JVMFlag::KIND_MANAGEABLE;
const int EXPERIMENTAL = JVMFlag::KIND_EXPERIMENTAL; const int EXPERIMENTAL = JVMFlag::KIND_EXPERIMENTAL;
#define MATERIALIZE_ALL_FLAGS \ #define MATERIALIZE_ALL_FLAGS \
ALL_FLAGS(DEVELOP_FLAG_INIT, \ ALL_FLAGS(INITIALIZE_DEVELOP_FLAG, \
DEVELOP_FLAG_INIT_PD, \ INITIALIZE_DEVELOP_FLAG_PD, \
PRODUCT_FLAG_INIT, \ INITIALIZE_PRODUCT_FLAG, \
PRODUCT_FLAG_INIT_PD, \ INITIALIZE_PRODUCT_FLAG_PD, \
NOTPROD_FLAG_INIT, \ INITIALIZE_NOTPROD_FLAG, \
IGNORE_RANGE, \ IGNORE_RANGE, \
IGNORE_CONSTRAINT) IGNORE_CONSTRAINT)
@ -779,413 +610,29 @@ JVMFlag* JVMFlag::fuzzy_match(const char* name, size_t length, bool allow_locked
return match; return match;
} }
// Returns the address of the index'th element bool JVMFlag::is_default(JVMFlagsEnum flag) {
JVMFlag* JVMFlagEx::flag_from_enum(JVMFlagsEnum flag) {
assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index");
return &JVMFlag::flags[flag];
}
bool JVMFlagEx::is_default(JVMFlagsEnum flag) {
return flag_from_enum(flag)->is_default(); return flag_from_enum(flag)->is_default();
} }
bool JVMFlagEx::is_ergo(JVMFlagsEnum flag) { bool JVMFlag::is_ergo(JVMFlagsEnum flag) {
return flag_from_enum(flag)->is_ergonomic(); return flag_from_enum(flag)->is_ergonomic();
} }
bool JVMFlagEx::is_cmdline(JVMFlagsEnum flag) { bool JVMFlag::is_cmdline(JVMFlagsEnum flag) {
return flag_from_enum(flag)->is_command_line(); return flag_from_enum(flag)->is_command_line();
} }
bool JVMFlagEx::is_jimage_resource(JVMFlagsEnum flag) { bool JVMFlag::is_jimage_resource(JVMFlagsEnum flag) {
assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index"); return flag_from_enum(flag)->is_jimage_resource();
JVMFlag* f = &JVMFlag::flags[flag];
return f->is_jimage_resource();
} }
void JVMFlagEx::setOnCmdLine(JVMFlagsEnum flag) { void JVMFlag::setOnCmdLine(JVMFlagsEnum flag) {
JVMFlag* faddr = flag_from_enum(flag); flag_from_enum(flag)->set_command_line();
assert(faddr != NULL, "Unknown flag");
faddr->set_command_line();
}
template<class E, class T>
static void trace_flag_changed(JVMFlag* flag, const T old_value, const T new_value, const JVMFlag::Flags origin) {
E e;
e.set_name(flag->_name);
e.set_oldValue(old_value);
e.set_newValue(new_value);
e.set_origin(origin);
e.commit();
}
static JVMFlag::Error apply_constraint_and_check_range_bool(JVMFlag* flag, bool new_value, bool verbose) {
JVMFlag::Error status = JVMFlag::SUCCESS;
JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
if (constraint.exists()) {
status = constraint.apply_bool(new_value, verbose);
}
return status;
}
JVMFlag::Error JVMFlag::boolAt(const JVMFlag* flag, bool* value) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_bool()) return JVMFlag::WRONG_FORMAT;
*value = flag->get_bool();
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlag::boolAtPut(JVMFlag* flag, bool* value, JVMFlag::Flags origin) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_bool()) return JVMFlag::WRONG_FORMAT;
JVMFlag::Error check = apply_constraint_and_check_range_bool(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
if (check != JVMFlag::SUCCESS) return check;
bool old_value = flag->get_bool();
trace_flag_changed<EventBooleanFlagChanged, bool>(flag, old_value, *value, origin);
flag->set_bool(*value);
*value = old_value;
flag->set_origin(origin);
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlagEx::boolAtPut(JVMFlagsEnum flag, bool value, JVMFlag::Flags origin) {
JVMFlag* faddr = flag_from_enum(flag);
guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
return JVMFlag::boolAtPut(faddr, &value, origin);
}
static JVMFlag::Error apply_constraint_and_check_range_int(JVMFlag* flag, int new_value, bool verbose) {
JVMFlag::Error status = JVMFlag::SUCCESS;
JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
if (range.exists()) {
status = range.check_int(new_value, verbose);
}
if (status == JVMFlag::SUCCESS) {
JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
if (constraint.exists()) {
status = constraint.apply_int(new_value, verbose);
}
}
return status;
}
JVMFlag::Error JVMFlag::intAt(const JVMFlag* flag, int* value) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_int()) return JVMFlag::WRONG_FORMAT;
*value = flag->get_int();
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlag::intAtPut(JVMFlag* flag, int* value, JVMFlag::Flags origin) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_int()) return JVMFlag::WRONG_FORMAT;
JVMFlag::Error check = apply_constraint_and_check_range_int(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
if (check != JVMFlag::SUCCESS) return check;
int old_value = flag->get_int();
trace_flag_changed<EventIntFlagChanged, s4>(flag, old_value, *value, origin);
flag->set_int(*value);
*value = old_value;
flag->set_origin(origin);
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlagEx::intAtPut(JVMFlagsEnum flag, int value, JVMFlag::Flags origin) {
JVMFlag* faddr = flag_from_enum(flag);
guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
return JVMFlag::intAtPut(faddr, &value, origin);
}
static JVMFlag::Error apply_constraint_and_check_range_uint(JVMFlag* flag, uint new_value, bool verbose) {
JVMFlag::Error status = JVMFlag::SUCCESS;
JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
if (range.exists()) {
status = range.check_uint(new_value, verbose);
}
if (status == JVMFlag::SUCCESS) {
JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
if (constraint.exists()) {
status = constraint.apply_uint(new_value, verbose);
}
}
return status;
}
JVMFlag::Error JVMFlag::uintAt(const JVMFlag* flag, uint* value) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_uint()) return JVMFlag::WRONG_FORMAT;
*value = flag->get_uint();
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlag::uintAtPut(JVMFlag* flag, uint* value, JVMFlag::Flags origin) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_uint()) return JVMFlag::WRONG_FORMAT;
JVMFlag::Error check = apply_constraint_and_check_range_uint(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
if (check != JVMFlag::SUCCESS) return check;
uint old_value = flag->get_uint();
trace_flag_changed<EventUnsignedIntFlagChanged, u4>(flag, old_value, *value, origin);
flag->set_uint(*value);
*value = old_value;
flag->set_origin(origin);
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlagEx::uintAtPut(JVMFlagsEnum flag, uint value, JVMFlag::Flags origin) {
JVMFlag* faddr = flag_from_enum(flag);
guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
return JVMFlag::uintAtPut(faddr, &value, origin);
}
JVMFlag::Error JVMFlag::intxAt(const JVMFlag* flag, intx* value) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_intx()) return JVMFlag::WRONG_FORMAT;
*value = flag->get_intx();
return JVMFlag::SUCCESS;
}
static JVMFlag::Error apply_constraint_and_check_range_intx(JVMFlag* flag, intx new_value, bool verbose) {
JVMFlag::Error status = JVMFlag::SUCCESS;
JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
if (range.exists()) {
status = range.check_intx(new_value, verbose);
}
if (status == JVMFlag::SUCCESS) {
JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
if (constraint.exists()) {
status = constraint.apply_intx(new_value, verbose);
}
}
return status;
}
JVMFlag::Error JVMFlag::intxAtPut(JVMFlag* flag, intx* value, JVMFlag::Flags origin) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_intx()) return JVMFlag::WRONG_FORMAT;
JVMFlag::Error check = apply_constraint_and_check_range_intx(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
if (check != JVMFlag::SUCCESS) return check;
intx old_value = flag->get_intx();
trace_flag_changed<EventLongFlagChanged, intx>(flag, old_value, *value, origin);
flag->set_intx(*value);
*value = old_value;
flag->set_origin(origin);
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlagEx::intxAtPut(JVMFlagsEnum flag, intx value, JVMFlag::Flags origin) {
JVMFlag* faddr = flag_from_enum(flag);
guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
return JVMFlag::intxAtPut(faddr, &value, origin);
}
JVMFlag::Error JVMFlag::uintxAt(const JVMFlag* flag, uintx* value) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_uintx()) return JVMFlag::WRONG_FORMAT;
*value = flag->get_uintx();
return JVMFlag::SUCCESS;
}
static JVMFlag::Error apply_constraint_and_check_range_uintx(JVMFlag* flag, uintx new_value, bool verbose) {
JVMFlag::Error status = JVMFlag::SUCCESS;
JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
if (range.exists()) {
status = range.check_uintx(new_value, verbose);
}
if (status == JVMFlag::SUCCESS) {
JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
if (constraint.exists()) {
status = constraint.apply_uintx(new_value, verbose);
}
}
return status;
}
JVMFlag::Error JVMFlag::uintxAtPut(JVMFlag* flag, uintx* value, JVMFlag::Flags origin) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_uintx()) return JVMFlag::WRONG_FORMAT;
JVMFlag::Error check = apply_constraint_and_check_range_uintx(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
if (check != JVMFlag::SUCCESS) return check;
uintx old_value = flag->get_uintx();
trace_flag_changed<EventUnsignedLongFlagChanged, u8>(flag, old_value, *value, origin);
flag->set_uintx(*value);
*value = old_value;
flag->set_origin(origin);
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlagEx::uintxAtPut(JVMFlagsEnum flag, uintx value, JVMFlag::Flags origin) {
JVMFlag* faddr = flag_from_enum(flag);
guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
return JVMFlag::uintxAtPut(faddr, &value, origin);
}
JVMFlag::Error JVMFlag::uint64_tAt(const JVMFlag* flag, uint64_t* value) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_uint64_t()) return JVMFlag::WRONG_FORMAT;
*value = flag->get_uint64_t();
return JVMFlag::SUCCESS;
}
static JVMFlag::Error apply_constraint_and_check_range_uint64_t(JVMFlag* flag, uint64_t new_value, bool verbose) {
JVMFlag::Error status = JVMFlag::SUCCESS;
JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
if (range.exists()) {
status = range.check_uint64_t(new_value, verbose);
}
if (status == JVMFlag::SUCCESS) {
JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
if (constraint.exists()) {
status = constraint.apply_uint64_t(new_value, verbose);
}
}
return status;
}
JVMFlag::Error JVMFlag::uint64_tAtPut(JVMFlag* flag, uint64_t* value, JVMFlag::Flags origin) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_uint64_t()) return JVMFlag::WRONG_FORMAT;
JVMFlag::Error check = apply_constraint_and_check_range_uint64_t(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
if (check != JVMFlag::SUCCESS) return check;
uint64_t old_value = flag->get_uint64_t();
trace_flag_changed<EventUnsignedLongFlagChanged, u8>(flag, old_value, *value, origin);
flag->set_uint64_t(*value);
*value = old_value;
flag->set_origin(origin);
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlagEx::uint64_tAtPut(JVMFlagsEnum flag, uint64_t value, JVMFlag::Flags origin) {
JVMFlag* faddr = flag_from_enum(flag);
guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
return JVMFlag::uint64_tAtPut(faddr, &value, origin);
}
JVMFlag::Error JVMFlag::size_tAt(const JVMFlag* flag, size_t* value) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_size_t()) return JVMFlag::WRONG_FORMAT;
*value = flag->get_size_t();
return JVMFlag::SUCCESS;
}
static JVMFlag::Error apply_constraint_and_check_range_size_t(JVMFlag* flag, size_t new_value, bool verbose) {
JVMFlag::Error status = JVMFlag::SUCCESS;
JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
if (range.exists()) {
status = range.check_size_t(new_value, verbose);
}
if (status == JVMFlag::SUCCESS) {
JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
if (constraint.exists()) {
status = constraint.apply_size_t(new_value, verbose);
}
}
return status;
}
JVMFlag::Error JVMFlag::size_tAtPut(JVMFlag* flag, size_t* value, JVMFlag::Flags origin) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_size_t()) return JVMFlag::WRONG_FORMAT;
JVMFlag::Error check = apply_constraint_and_check_range_size_t(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
if (check != JVMFlag::SUCCESS) return check;
size_t old_value = flag->get_size_t();
trace_flag_changed<EventUnsignedLongFlagChanged, u8>(flag, old_value, *value, origin);
flag->set_size_t(*value);
*value = old_value;
flag->set_origin(origin);
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlagEx::size_tAtPut(JVMFlagsEnum flag, size_t value, JVMFlag::Flags origin) {
JVMFlag* faddr = flag_from_enum(flag);
guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
return JVMFlag::size_tAtPut(faddr, &value, origin);
}
JVMFlag::Error JVMFlag::doubleAt(const JVMFlag* flag, double* value) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_double()) return JVMFlag::WRONG_FORMAT;
*value = flag->get_double();
return JVMFlag::SUCCESS;
}
static JVMFlag::Error apply_constraint_and_check_range_double(JVMFlag* flag, double new_value, bool verbose) {
JVMFlag::Error status = JVMFlag::SUCCESS;
JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
if (range.exists()) {
status = range.check_double(new_value, verbose);
}
if (status == JVMFlag::SUCCESS) {
JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
if (constraint.exists()) {
status = constraint.apply_double(new_value, verbose);
}
}
return status;
}
JVMFlag::Error JVMFlag::doubleAtPut(JVMFlag* flag, double* value, JVMFlag::Flags origin) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_double()) return JVMFlag::WRONG_FORMAT;
JVMFlag::Error check = apply_constraint_and_check_range_double(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
if (check != JVMFlag::SUCCESS) return check;
double old_value = flag->get_double();
trace_flag_changed<EventDoubleFlagChanged, double>(flag, old_value, *value, origin);
flag->set_double(*value);
*value = old_value;
flag->set_origin(origin);
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlagEx::doubleAtPut(JVMFlagsEnum flag, double value, JVMFlag::Flags origin) {
JVMFlag* faddr = flag_from_enum(flag);
guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
return JVMFlag::doubleAtPut(faddr, &value, origin);
}
JVMFlag::Error JVMFlag::ccstrAt(const JVMFlag* flag, ccstr* value) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_ccstr()) return JVMFlag::WRONG_FORMAT;
*value = flag->get_ccstr();
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlag::ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlag::Flags origin) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_ccstr()) return JVMFlag::WRONG_FORMAT;
ccstr old_value = flag->get_ccstr();
trace_flag_changed<EventStringFlagChanged, const char*>(flag, old_value, *value, origin);
char* new_value = NULL;
if (*value != NULL) {
new_value = os::strdup_check_oom(*value);
}
flag->set_ccstr(new_value);
if (flag->is_default() && old_value != NULL) {
// Prior value is NOT heap allocated, but was a literal constant.
old_value = os::strdup_check_oom(old_value);
}
*value = old_value;
flag->set_origin(origin);
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlagEx::ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlag::Flags origin) {
JVMFlag* faddr = flag_from_enum(flag);
guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
ccstr old_value = faddr->get_ccstr();
trace_flag_changed<EventStringFlagChanged, const char*>(faddr, old_value, value, origin);
char* new_value = os::strdup_check_oom(value);
faddr->set_ccstr(new_value);
if (!faddr->is_default() && old_value != NULL) {
// Prior value is heap allocated so free it.
FREE_C_HEAP_ARRAY(char, old_value);
}
faddr->set_origin(origin);
return JVMFlag::SUCCESS;
} }
extern "C" { extern "C" {
static int compare_flags(const void* void_a, const void* void_b) { static int compare_flags(const void* void_a, const void* void_b) {
return strcmp((*((JVMFlag**) void_a))->_name, (*((JVMFlag**) void_b))->_name); return strcmp((*((JVMFlag**) void_a))->name(), (*((JVMFlag**) void_b))->name());
} }
} }
@ -1225,8 +672,8 @@ void JVMFlag::verify() {
#ifdef ASSERT #ifdef ASSERT
void JVMFlag::assert_valid_flag_enum(int i) { void JVMFlag::assert_valid_flag_enum(JVMFlagsEnum i) {
assert(0 <= i && i < NUM_JVMFlagsEnum, "must be"); assert(0 <= int(i) && int(i) < NUM_JVMFlagsEnum, "must be");
} }
void JVMFlag::check_all_flag_declarations() { void JVMFlag::check_all_flag_declarations() {

View file

@ -28,12 +28,13 @@
#include "utilities/globalDefinitions.hpp" #include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp" #include "utilities/macros.hpp"
enum JVMFlagsEnum : int;
class outputStream; class outputStream;
// function type that will construct default range string class JVMFlag {
typedef const char* (*RangeStrFunc)(void); friend class VMStructs;
public:
struct JVMFlag {
enum Flags : int { enum Flags : int {
// latest value origin // latest value origin
DEFAULT = 0, DEFAULT = 0,
@ -105,12 +106,36 @@ struct JVMFlag {
NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD
}; };
const char* _type; #define JVM_FLAG_NON_STRING_TYPES_DO(f) \
const char* _name; f(bool) \
f(int) \
f(uint) \
f(intx) \
f(uintx) \
f(uint64_t) \
f(size_t) \
f(double)
#define JVM_FLAG_TYPE_DECLARE(t) \
TYPE_ ## t,
enum FlagType : int {
JVM_FLAG_NON_STRING_TYPES_DO(JVM_FLAG_TYPE_DECLARE)
// The two string types are a bit irregular: is_ccstr() returns true for both types.
TYPE_ccstr,
TYPE_ccstrlist,
NUM_FLAG_TYPES
};
private:
void* _addr; void* _addr;
const char* _name;
Flags _flags; Flags _flags;
int _type;
NOT_PRODUCT(const char* _doc;) NOT_PRODUCT(const char* _doc;)
public:
// points to all Flags static array // points to all Flags static array
static JVMFlag* flags; static JVMFlag* flags;
@ -121,12 +146,12 @@ private:
static JVMFlag* find_flag(const char* name, size_t length, bool allow_locked, bool return_flag); static JVMFlag* find_flag(const char* name, size_t length, bool allow_locked, bool return_flag);
public: public:
constexpr JVMFlag() : _type(), _name(), _addr(), _flags() NOT_PRODUCT(COMMA _doc()) {} constexpr JVMFlag() : _addr(), _name(), _flags(), _type() NOT_PRODUCT(COMMA _doc()) {}
constexpr JVMFlag(int flag_enum, const char* type, const char* name, constexpr JVMFlag(int flag_enum, FlagType type, const char* name,
void* addr, int flags, int extra_flags, const char* doc); void* addr, int flags, int extra_flags, const char* doc);
constexpr JVMFlag(int flag_enum, const char* type, const char* name, constexpr JVMFlag(int flag_enum, FlagType type, const char* name,
void* addr, int flags, const char* doc); void* addr, int flags, const char* doc);
static JVMFlag* find_flag(const char* name) { static JVMFlag* find_flag(const char* name) {
@ -141,87 +166,97 @@ public:
static JVMFlag* fuzzy_match(const char* name, size_t length, bool allow_locked = false); static JVMFlag* fuzzy_match(const char* name, size_t length, bool allow_locked = false);
static const char* get_int_default_range_str(); static void assert_valid_flag_enum(JVMFlagsEnum i) NOT_DEBUG_RETURN;
static const char* get_uint_default_range_str();
static const char* get_intx_default_range_str();
static const char* get_uintx_default_range_str();
static const char* get_uint64_t_default_range_str();
static const char* get_size_t_default_range_str();
static const char* get_double_default_range_str();
static void assert_valid_flag_enum(int i) NOT_DEBUG_RETURN;
static void check_all_flag_declarations() NOT_DEBUG_RETURN; static void check_all_flag_declarations() NOT_DEBUG_RETURN;
inline int flag_enum() const { inline JVMFlagsEnum flag_enum() const {
int i = this - JVMFlag::flags; JVMFlagsEnum i = static_cast<JVMFlagsEnum>(this - JVMFlag::flags);
assert_valid_flag_enum(i); assert_valid_flag_enum(i);
return i; return i;
} }
static JVMFlag* flag_from_enum(int flag_enum) { static JVMFlag* flag_from_enum(JVMFlagsEnum flag_enum) {
assert_valid_flag_enum(flag_enum); assert_valid_flag_enum(flag_enum);
return &JVMFlag::flags[flag_enum]; return &JVMFlag::flags[flag_enum];
} }
bool is_bool() const; #define JVM_FLAG_TYPE_ACCESSOR(t) \
bool get_bool() const { return *((bool*) _addr); } bool is_##t() const { return _type == TYPE_##t;} \
void set_bool(bool value) const { *((bool*) _addr) = value; } t get_##t() const { assert(is_##t(), "sanity"); return *((t*) _addr); } \
void set_##t(t value) { assert(is_##t(), "sanity"); *((t*) _addr) = value; }
bool is_int() const; JVM_FLAG_NON_STRING_TYPES_DO(JVM_FLAG_TYPE_ACCESSOR)
int get_int() const { return *((int*) _addr); }
void set_int(int value) const { *((int*) _addr) = value; }
bool is_uint() const; bool is_ccstr() const { return _type == TYPE_ccstr || _type == TYPE_ccstrlist; }
uint get_uint() const { return *((uint*) _addr); } bool ccstr_accumulates() const { return _type == TYPE_ccstrlist; }
void set_uint(uint value) const { *((uint*) _addr) = value; } ccstr get_ccstr() const { assert(is_ccstr(), "sanity"); return *((ccstr*) _addr); }
void set_ccstr(ccstr value) { assert(is_ccstr(), "sanity"); *((ccstr*) _addr) = value; }
bool is_intx() const; #define JVM_FLAG_AS_STRING(t) \
intx get_intx() const { return *((intx*) _addr); } case TYPE_##t: return STR(t);
void set_intx(intx value) const { *((intx*) _addr) = value; }
bool is_uintx() const; const char* type_string() const {
uintx get_uintx() const { return *((uintx*) _addr); } return type_string_for((FlagType)_type);
void set_uintx(uintx value) const { *((uintx*) _addr) = value; } }
bool is_uint64_t() const; static const char* type_string_for(FlagType t) {
uint64_t get_uint64_t() const { return *((uint64_t*) _addr); } switch(t) {
void set_uint64_t(uint64_t value) const { *((uint64_t*) _addr) = value; } JVM_FLAG_NON_STRING_TYPES_DO(JVM_FLAG_AS_STRING)
case TYPE_ccstr: return "ccstr";
case TYPE_ccstrlist: return "ccstrlist";
default:
ShouldNotReachHere();
return "unknown";
}
}
bool is_size_t() const; int type() const { return _type; }
size_t get_size_t() const { return *((size_t*) _addr); } const char* name() const { return _name; }
void set_size_t(size_t value) const { *((size_t*) _addr) = value; }
bool is_double() const; void assert_type(int type_enum) const {
double get_double() const { return *((double*) _addr); } if (type_enum == JVMFlag::TYPE_ccstr) {
void set_double(double value) const { *((double*) _addr) = value; } assert(is_ccstr(), "type check"); // ccstr or ccstrlist
} else {
assert(_type == type_enum, "type check");
}
}
bool is_ccstr() const; // Do not use JVMFlag::read() or JVMFlag::write() directly unless you know
bool ccstr_accumulates() const; // what you're doing. Use FLAG_SET_XXX macros or JVMFlagAccess instead.
ccstr get_ccstr() const { return *((ccstr*) _addr); } template <typename T, int type_enum> T read() const {
void set_ccstr(ccstr value) const { *((ccstr*) _addr) = value; } assert_type(type_enum);
return *static_cast<T*>(_addr);
}
Flags get_origin() const; template <typename T, int type_enum> void write(T value) {
assert_type(type_enum);
*static_cast<T*>(_addr) = value;
}
Flags get_origin() const { return Flags(_flags & VALUE_ORIGIN_MASK); }
void set_origin(Flags origin); void set_origin(Flags origin);
bool is_default() const; bool is_default() const { return (get_origin() == DEFAULT); }
bool is_ergonomic() const; bool is_ergonomic() const { return (get_origin() == ERGONOMIC); }
bool is_jimage_resource() const; bool is_command_line() const { return (_flags & ORIG_COMMAND_LINE) != 0; }
bool is_command_line() const; void set_command_line() { _flags = Flags(_flags | ORIG_COMMAND_LINE); }
void set_command_line(); bool is_jimage_resource() const { return (get_origin() == JIMAGE_RESOURCE); }
bool is_product() const { return (_flags & KIND_PRODUCT) != 0; }
bool is_product() const; bool is_manageable() const { return (_flags & KIND_MANAGEABLE) != 0; }
bool is_manageable() const; bool is_diagnostic() const { return (_flags & KIND_DIAGNOSTIC) != 0; }
bool is_diagnostic() const; bool is_experimental() const { return (_flags & KIND_EXPERIMENTAL) != 0; }
bool is_experimental() const; bool is_notproduct() const { return (_flags & KIND_NOT_PRODUCT) != 0; }
bool is_notproduct() const; bool is_develop() const { return (_flags & KIND_DEVELOP) != 0; }
bool is_develop() const;
bool is_constant_in_binary() const; bool is_constant_in_binary() const;
bool is_unlocker() const; bool is_unlocker() const;
bool is_unlocked() const; bool is_unlocked() const;
bool is_writeable() const;
bool is_external() const; // Only manageable flags can be accessed by writeableFlags.cpp
bool is_writeable() const { return is_manageable(); }
// All flags except "manageable" are assumed to be internal flags.
bool is_external() const { return is_manageable(); }
void clear_diagnostic(); void clear_diagnostic();
void clear_experimental(); void clear_experimental();
@ -230,6 +265,13 @@ public:
JVMFlag::MsgType get_locked_message(char*, int) const; JVMFlag::MsgType get_locked_message(char*, int) const;
JVMFlag::MsgType get_locked_message_ext(char*, int) const; JVMFlag::MsgType get_locked_message_ext(char*, int) const;
static bool is_default(JVMFlagsEnum flag);
static bool is_ergo(JVMFlagsEnum flag);
static bool is_cmdline(JVMFlagsEnum flag);
static bool is_jimage_resource(JVMFlagsEnum flag);
static void setOnCmdLine(JVMFlagsEnum flag);
// printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges // printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges
void print_on(outputStream* st, bool withComments = false, bool printRanges = false) const; void print_on(outputStream* st, bool withComments = false, bool printRanges = false) const;
void print_kind(outputStream* st, unsigned int width) const; void print_kind(outputStream* st, unsigned int width) const;
@ -239,35 +281,6 @@ public:
static const char* flag_error_str(JVMFlag::Error error); static const char* flag_error_str(JVMFlag::Error error);
public: public:
static JVMFlag::Error boolAt(const JVMFlag* flag, bool* value);
static JVMFlag::Error boolAtPut(JVMFlag* flag, bool* value, JVMFlag::Flags origin);
static JVMFlag::Error intAt(const JVMFlag* flag, int* value);
static JVMFlag::Error intAtPut(JVMFlag* flag, int* value, JVMFlag::Flags origin);
static JVMFlag::Error uintAt(const JVMFlag* flag, uint* value);
static JVMFlag::Error uintAtPut(JVMFlag* flag, uint* value, JVMFlag::Flags origin);
static JVMFlag::Error intxAt(const JVMFlag* flag, intx* value);
static JVMFlag::Error intxAtPut(JVMFlag* flag, intx* value, JVMFlag::Flags origin);
static JVMFlag::Error uintxAt(const JVMFlag* flag, uintx* value);
static JVMFlag::Error uintxAtPut(JVMFlag* flag, uintx* value, JVMFlag::Flags origin);
static JVMFlag::Error size_tAt(const JVMFlag* flag, size_t* value);
static JVMFlag::Error size_tAtPut(JVMFlag* flag, size_t* value, JVMFlag::Flags origin);
static JVMFlag::Error uint64_tAt(const JVMFlag* flag, uint64_t* value);
static JVMFlag::Error uint64_tAtPut(JVMFlag* flag, uint64_t* value, JVMFlag::Flags origin);
static JVMFlag::Error doubleAt(const JVMFlag* flag, double* value);
static JVMFlag::Error doubleAtPut(JVMFlag* flag, double* value, JVMFlag::Flags origin);
static JVMFlag::Error ccstrAt(const JVMFlag* flag, ccstr* value);
// Contract: JVMFlag will make private copy of the incoming value.
// Outgoing value is always malloc-ed, and caller MUST call free.
static JVMFlag::Error ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlag::Flags origin);
static void printSetFlags(outputStream* out); static void printSetFlags(outputStream* out);
// printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges // printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges

View file

@ -0,0 +1,397 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "jfr/jfrEvents.hpp"
#include "memory/allocation.hpp"
#include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagAccess.hpp"
#include "runtime/flags/jvmFlagLimit.hpp"
#include "runtime/flags/jvmFlagConstraintsRuntime.hpp"
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
template<typename T, typename EVENT>
static void trace_flag_changed(JVMFlag* flag, const T old_value, const T new_value, const JVMFlag::Flags origin) {
EVENT e;
e.set_name(flag->name());
e.set_oldValue(old_value);
e.set_newValue(new_value);
e.set_origin(origin);
e.commit();
}
class FlagAccessImpl {
public:
JVMFlag::Error set(JVMFlag* flag, void* value, JVMFlag::Flags origin) const {
return set_impl(flag, value, origin);
}
virtual JVMFlag::Error set_impl(JVMFlag* flag, void* value, JVMFlag::Flags origin) const = 0;
virtual JVMFlag::Error check_range(const JVMFlag* flag, bool verbose) const { return JVMFlag::SUCCESS; }
virtual void print_range(outputStream* st, const JVMFlagLimit* range) const { ShouldNotReachHere(); }
virtual void print_default_range(outputStream* st) const { ShouldNotReachHere(); }
virtual JVMFlag::Error check_constraint(const JVMFlag* flag, void * func, bool verbose) const { return JVMFlag::SUCCESS; }
};
template <typename T, int type_enum, typename EVENT>
class TypedFlagAccessImpl : public FlagAccessImpl {
public:
JVMFlag::Error check_constraint_and_set(JVMFlag* flag, void* value_addr, JVMFlag::Flags origin, bool verbose) const {
T value = *((T*)value_addr);
const JVMTypedFlagLimit<T>* constraint = (const JVMTypedFlagLimit<T>*)JVMFlagLimit::get_constraint(flag);
if (constraint != NULL && constraint->phase() <= static_cast<int>(JVMFlagLimit::validating_phase())) {
JVMFlag::Error err = typed_check_constraint(constraint->constraint_func(), value, verbose);
if (err != JVMFlag::SUCCESS) {
return err;
}
}
T old_value = flag->read<T, type_enum>();
trace_flag_changed<T, EVENT>(flag, old_value, value, origin);
flag->write<T, type_enum>(value);
*((T*)value_addr) = old_value;
flag->set_origin(origin);
return JVMFlag::SUCCESS;
}
JVMFlag::Error check_constraint(const JVMFlag* flag, void * func, bool verbose) const {
return typed_check_constraint(func, flag->read<T, type_enum>(), verbose);
}
virtual JVMFlag::Error typed_check_constraint(void * func, T value, bool verbose) const = 0;
};
class FlagAccessImpl_bool : public TypedFlagAccessImpl<JVM_FLAG_TYPE(bool), EventBooleanFlagChanged> {
public:
JVMFlag::Error set_impl(JVMFlag* flag, void* value_addr, JVMFlag::Flags origin) const {
bool verbose = JVMFlagLimit::verbose_checks_needed();
return TypedFlagAccessImpl<JVM_FLAG_TYPE(bool), EventBooleanFlagChanged>
::check_constraint_and_set(flag, value_addr, origin, verbose);
}
JVMFlag::Error typed_check_constraint(void* func, bool value, bool verbose) const {
return ((JVMFlagConstraintFunc_bool)func)(value, verbose);
}
};
template <typename T, int type_enum, typename EVENT>
class RangedFlagAccessImpl : public TypedFlagAccessImpl<T, type_enum, EVENT> {
public:
virtual JVMFlag::Error set_impl(JVMFlag* flag, void* value_addr, JVMFlag::Flags origin) const {
T value = *((T*)value_addr);
bool verbose = JVMFlagLimit::verbose_checks_needed();
const JVMTypedFlagLimit<T>* range = (const JVMTypedFlagLimit<T>*)JVMFlagLimit::get_range(flag);
if (range != NULL) {
if ((value < range->min()) || (value > range->max())) {
range_error(flag->name(), value, range->min(), range->max(), verbose);
return JVMFlag::OUT_OF_BOUNDS;
}
}
return TypedFlagAccessImpl<T, type_enum, EVENT>::check_constraint_and_set(flag, value_addr, origin, verbose);
}
virtual JVMFlag::Error check_range(const JVMFlag* flag, bool verbose) const {
const JVMTypedFlagLimit<T>* range = (const JVMTypedFlagLimit<T>*)JVMFlagLimit::get_range(flag);
if (range != NULL) {
T value = flag->read<T, type_enum>();
if ((value < range->min()) || (value > range->max())) {
range_error(flag->name(), value, range->min(), range->max(), verbose);
return JVMFlag::OUT_OF_BOUNDS;
}
}
return JVMFlag::SUCCESS;
}
virtual void print_range(outputStream* st, const JVMFlagLimit* range) const {
const JVMTypedFlagLimit<T>* r = (const JVMTypedFlagLimit<T>*)range;
print_range_impl(st, r->min(), r->max());
}
virtual void range_error(const char* name, T value, T min, T max, bool verbose) const = 0;
virtual void print_range_impl(outputStream* st, T min, T max) const = 0;
};
class FlagAccessImpl_int : public RangedFlagAccessImpl<JVM_FLAG_TYPE(int), EventIntFlagChanged> {
public:
void range_error(const char* name, int value, int min, int max, bool verbose) const {
JVMFlag::printError(verbose,
"int %s=%d is outside the allowed range "
"[ %d ... %d ]\n",
name, value, min, max);
}
JVMFlag::Error typed_check_constraint(void* func, int value, bool verbose) const {
return ((JVMFlagConstraintFunc_int)func)(value, verbose);
}
void print_range_impl(outputStream* st, int min, int max) const {
st->print("[ %-25d ... %25d ]", min, max);
}
void print_default_range(outputStream* st) const {
st->print("[ " INT32_FORMAT_W(-25) " ... " INT32_FORMAT_W(25) " ]", INT_MIN, INT_MAX);
}
};
class FlagAccessImpl_uint : public RangedFlagAccessImpl<JVM_FLAG_TYPE(uint), EventUnsignedIntFlagChanged> {
public:
void range_error(const char* name, uint value, uint min, uint max, bool verbose) const {
JVMFlag::printError(verbose,
"uint %s=%u is outside the allowed range "
"[ %u ... %u ]\n",
name, value, min, max);
}
JVMFlag::Error typed_check_constraint(void* func, uint value, bool verbose) const {
return ((JVMFlagConstraintFunc_uint)func)(value, verbose);
}
void print_range_impl(outputStream* st, uint min, uint max) const {
st->print("[ %-25u ... %25u ]", min, max);
}
void print_default_range(outputStream* st) const {
st->print("[ " UINT32_FORMAT_W(-25) " ... " UINT32_FORMAT_W(25) " ]", 0, UINT_MAX);
}
};
class FlagAccessImpl_intx : public RangedFlagAccessImpl<JVM_FLAG_TYPE(intx), EventLongFlagChanged> {
public:
void range_error(const char* name, intx value, intx min, intx max, bool verbose) const {
JVMFlag::printError(verbose,
"intx %s=" INTX_FORMAT " is outside the allowed range "
"[ " INTX_FORMAT " ... " INTX_FORMAT " ]\n",
name, value, min, max);
}
JVMFlag::Error typed_check_constraint(void* func, intx value, bool verbose) const {
return ((JVMFlagConstraintFunc_intx)func)(value, verbose);
}
void print_range_impl(outputStream* st, intx min, intx max) const {
st->print("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", min, max);
}
void print_default_range(outputStream* st) const {
st->print("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", min_intx, max_intx);
}
};
class FlagAccessImpl_uintx : public RangedFlagAccessImpl<JVM_FLAG_TYPE(uintx), EventUnsignedLongFlagChanged> {
public:
void range_error(const char* name, uintx value, uintx min, uintx max, bool verbose) const {
JVMFlag::printError(verbose,
"uintx %s=" UINTX_FORMAT " is outside the allowed range "
"[ " UINTX_FORMAT " ... " UINTX_FORMAT " ]\n",
name, value, min, max);
}
JVMFlag::Error typed_check_constraint(void* func, uintx value, bool verbose) const {
return ((JVMFlagConstraintFunc_uintx)func)(value, verbose);
}
void print_range_impl(outputStream* st, uintx min, uintx max) const {
st->print("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", min, max);
}
void print_default_range(outputStream* st) const {
st->print("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", uintx(0), max_uintx);
}
};
class FlagAccessImpl_uint64_t : public RangedFlagAccessImpl<JVM_FLAG_TYPE(uint64_t), EventUnsignedLongFlagChanged> {
public:
void range_error(const char* name, uint64_t value, uint64_t min, uint64_t max, bool verbose) const {
JVMFlag::printError(verbose,
"uint64_t %s=" UINT64_FORMAT " is outside the allowed range "
"[ " UINT64_FORMAT " ... " UINT64_FORMAT " ]\n",
name, value, min, max);
}
JVMFlag::Error typed_check_constraint(void* func, uint64_t value, bool verbose) const {
return ((JVMFlagConstraintFunc_uint64_t)func)(value, verbose);
}
void print_range_impl(outputStream* st, uint64_t min, uint64_t max) const {
st->print("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", min, max);
}
void print_default_range(outputStream* st) const {
st->print("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", uint64_t(0), uint64_t(max_juint));
}
};
class FlagAccessImpl_size_t : public RangedFlagAccessImpl<JVM_FLAG_TYPE(size_t), EventUnsignedLongFlagChanged> {
public:
void range_error(const char* name, size_t value, size_t min, size_t max, bool verbose) const {
JVMFlag::printError(verbose,
"size_t %s=" SIZE_FORMAT " is outside the allowed range "
"[ " SIZE_FORMAT " ... " SIZE_FORMAT " ]\n",
name, value, min, max);
}
JVMFlag::Error typed_check_constraint(void* func, size_t value, bool verbose) const {
return ((JVMFlagConstraintFunc_size_t)func)(value, verbose);
}
void print_range_impl(outputStream* st, size_t min, size_t max) const {
st->print("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", min, max);
}
void print_default_range(outputStream* st) const {
st->print("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", size_t(0), SIZE_MAX);
}
};
class FlagAccessImpl_double : public RangedFlagAccessImpl<JVM_FLAG_TYPE(double), EventDoubleFlagChanged> {
public:
void range_error(const char* name, double value, double min, double max, bool verbose) const {
JVMFlag::printError(verbose,
"double %s=%f is outside the allowed range "
"[ %f ... %f ]\n",
name, value, min, max);
}
JVMFlag::Error typed_check_constraint(void* func, double value, bool verbose) const {
return ((JVMFlagConstraintFunc_double)func)(value, verbose);
}
void print_range_impl(outputStream* st, double min, double max) const {
st->print("[ %-25.3f ... %25.3f ]", min, max);
}
void print_default_range(outputStream* st) const {
st->print("[ %-25.3f ... %25.3f ]", DBL_MIN, DBL_MAX);
}
};
#define FLAG_ACCESS_IMPL_INIT(t) \
static FlagAccessImpl_ ## t flag_access_ ## t;
#define FLAG_ACCESS_IMPL_ADDR(t) \
&flag_access_ ## t,
JVM_FLAG_NON_STRING_TYPES_DO(FLAG_ACCESS_IMPL_INIT)
static const FlagAccessImpl* flag_accesss[JVMFlag::NUM_FLAG_TYPES] = {
JVM_FLAG_NON_STRING_TYPES_DO(FLAG_ACCESS_IMPL_ADDR)
// ccstr and ccstrlist have special setter
};
inline const FlagAccessImpl* JVMFlagAccess::access_impl(const JVMFlag* flag) {
int type = flag->type();
int max = (int)(sizeof(flag_accesss)/sizeof(flag_accesss[0]));
assert(type >= 0 && type < max , "sanity");
return flag_accesss[type];
}
// This is called by JVMFlagAccess::*AtPut() and JVMFlagAccess::set<...>(JVMFlag* flag, ...)
JVMFlag::Error JVMFlagAccess::set_impl(JVMFlag* flag, int type_enum, void* value, JVMFlag::Flags origin) {
if (type_enum == JVMFlag::TYPE_ccstr || type_enum == JVMFlag::TYPE_ccstrlist) {
return ccstrAtPut(flag, (ccstr*)value, origin);
}
if (flag == NULL) {
return JVMFlag::INVALID_FLAG;
}
if (flag->type() != type_enum) {
return JVMFlag::WRONG_FORMAT;
}
return access_impl(flag)->set(flag, value, origin);
}
JVMFlag::Error JVMFlagAccess::ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlag::Flags origin) {
if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_ccstr()) return JVMFlag::WRONG_FORMAT;
ccstr old_value = flag->get_ccstr();
trace_flag_changed<ccstr, EventStringFlagChanged>(flag, old_value, *value, origin);
char* new_value = NULL;
if (*value != NULL) {
new_value = os::strdup_check_oom(*value);
}
flag->set_ccstr(new_value);
if (flag->is_default() && old_value != NULL) {
// Prior value is NOT heap allocated, but was a literal constant.
old_value = os::strdup_check_oom(old_value);
}
*value = old_value;
flag->set_origin(origin);
return JVMFlag::SUCCESS;
}
// This is called by the FLAG_SET_XXX macros.
JVMFlag::Error JVMFlagAccess::set_impl(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlag::Flags origin) {
if (type_enum == JVMFlag::TYPE_ccstr || type_enum == JVMFlag::TYPE_ccstrlist) {
return ccstrAtPut((JVMFlagsEnum)flag_enum, *((ccstr*)value), origin);
}
JVMFlag* flag = JVMFlag::flag_from_enum(flag_enum);
assert(flag->type() == type_enum, "wrong flag type");
return set_impl(flag, type_enum, value, origin);
}
// This is called by the FLAG_SET_XXX macros.
JVMFlag::Error JVMFlagAccess::ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlag::Flags origin) {
JVMFlag* faddr = JVMFlag::flag_from_enum(flag);
assert(faddr->is_ccstr(), "wrong flag type");
ccstr old_value = faddr->get_ccstr();
trace_flag_changed<ccstr, EventStringFlagChanged>(faddr, old_value, value, origin);
char* new_value = os::strdup_check_oom(value);
faddr->set_ccstr(new_value);
if (!faddr->is_default() && old_value != NULL) {
// Prior value is heap allocated so free it.
FREE_C_HEAP_ARRAY(char, old_value);
}
faddr->set_origin(origin);
return JVMFlag::SUCCESS;
}
JVMFlag::Error JVMFlagAccess::check_range(const JVMFlag* flag, bool verbose) {
return access_impl(flag)->check_range(flag, verbose);
}
JVMFlag::Error JVMFlagAccess::check_constraint(const JVMFlag* flag, void * func, bool verbose) {
return access_impl(flag)->check_constraint(flag, func, verbose);
}
void JVMFlagAccess::print_range(outputStream* st, const JVMFlag* flag, const JVMFlagLimit* range) {
return access_impl(flag)->print_range(st, range);
}
void JVMFlagAccess::print_range(outputStream* st, const JVMFlag* flag) {
const JVMFlagLimit* range = JVMFlagLimit::get_range(flag);
if (range != NULL) {
print_range(st, flag, range);
} else {
const JVMFlagLimit* limit = JVMFlagLimit::get_constraint(flag);
if (limit != NULL) {
void* func = limit->constraint_func();
// Two special cases where the lower limit of the range is defined by an os:: function call
// and cannot be initialized at compile time with constexpr.
if (func == (void*)VMPageSizeConstraintFunc) {
uintx min = (uintx)os::vm_page_size();
uintx max = max_uintx;
JVMTypedFlagLimit<uintx> tmp(0, min, max);
access_impl(flag)->print_range(st, &tmp);
} else if (func == (void*)NUMAInterleaveGranularityConstraintFunc) {
size_t min = os::vm_allocation_granularity();
size_t max = NOT_LP64(2*G) LP64_ONLY(8192*G);
JVMTypedFlagLimit<size_t> tmp(0, min, max);
access_impl(flag)->print_range(st, &tmp);
} else {
access_impl(flag)->print_default_range(st);
}
} else {
st->print("[ ... ]");
}
}
}

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_RUNTIME_FLAGS_JVMFLAGACCESS_HPP
#define SHARE_RUNTIME_FLAGS_JVMFLAGACCESS_HPP
#include "memory/allStatic.hpp"
#include "runtime/flags/jvmFlag.hpp"
enum JVMFlagsEnum : int;
class FlagAccessImpl;
class JVMFlagLimit;
class outputStream;
// Use this macro in combination with JVMFlag::{read, write} and JVMFlagAccess::{get, set}
// to safely access the underlying variable of a JVMFlag:
//
// JVMFlag* flag = JVMFlag::flag_from_enum(FLAG_MEMBER_ENUM(ObjectAlignmentInBytes));
//
// /* If you use a wrong type, a run-time assertion will happen */
// intx v = flag->read<JVM_FLAG_TYPE(intx)>();
//
// /* If you use a wrong type, or a NULL flag, an error code is returned */
// JVMFlag::Error err = JVMFlagAccess::get<JVM_FLAG_TYPE(intx)>(flag, &v);
#define JVM_FLAG_TYPE(t) \
t, JVMFlag::TYPE_ ## t
// This class provides a unified interface for getting/setting the JVM flags, with support
// for (1) type correctness checks, (2) range checks, (3) constraint checks. Two main types
// of setters are provided. See notes below on which one to use.
class JVMFlagAccess : AllStatic {
inline static const FlagAccessImpl* access_impl(const JVMFlag* flag);
static JVMFlag::Error set_impl(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlag::Flags origin);
static JVMFlag::Error set_impl(JVMFlag* flag, int type_enum, void* value, JVMFlag::Flags origin);
static JVMFlag::Error ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlag::Flags origin);
public:
static JVMFlag::Error check_range(const JVMFlag* flag, bool verbose);
static JVMFlag::Error check_constraint(const JVMFlag* flag, void * func, bool verbose);
static void print_range(outputStream* st, const JVMFlag* flag, const JVMFlagLimit* range);
static void print_range(outputStream* st, const JVMFlag* flag);
template <typename T, int type_enum>
static JVMFlag::Error get(const JVMFlag* flag, T* value) {
if (flag == NULL) {
return JVMFlag::INVALID_FLAG;
}
if (type_enum == JVMFlag::TYPE_ccstr) {
if (!flag->is_ccstr()) { // ccstr or ccstrlist
return JVMFlag::WRONG_FORMAT;
}
} else {
if (flag->type() != type_enum) {
return JVMFlag::WRONG_FORMAT;
}
}
*value = flag->read<T, type_enum>();
return JVMFlag::SUCCESS;
}
// This is a *flag specific* setter. It should be used only via by the
// FLAG_SET_{DEFAULT, CMDLINE, ERGO, MGMT} macros.
// It's used to set a specific flag whose type is statically known. A mismatched
// type_enum will result in an assert.
template <typename T, int type_enum>
static JVMFlag::Error set(JVMFlagsEnum flag_enum, T value, JVMFlag::Flags origin) {
return set_impl(flag_enum, type_enum, &value, origin);
}
// This setter, and the xxxAtPut functions below, are *generic* setters. They should be used
// by code that can set a number of different flags, often according to external input that
// may contain errors.
// Examples callers are arguments.cpp, writeableFlags.cpp, and WB_SetXxxVMFlag functions.
// A mismatched type_enum would result in a JVMFlag::WRONG_FORMAT code.
template <typename T, int type_enum>
static JVMFlag::Error set(JVMFlag* flag, T* value, JVMFlag::Flags origin) {
return set_impl(flag, type_enum, (void*)value, origin);
}
static JVMFlag::Error boolAtPut (JVMFlag* f, bool* v, JVMFlag::Flags origin) { return set<JVM_FLAG_TYPE(bool)> (f, v, origin); }
static JVMFlag::Error intAtPut (JVMFlag* f, int* v, JVMFlag::Flags origin) { return set<JVM_FLAG_TYPE(int)> (f, v, origin); }
static JVMFlag::Error uintAtPut (JVMFlag* f, uint* v, JVMFlag::Flags origin) { return set<JVM_FLAG_TYPE(uint)> (f, v, origin); }
static JVMFlag::Error intxAtPut (JVMFlag* f, intx* v, JVMFlag::Flags origin) { return set<JVM_FLAG_TYPE(intx)> (f, v, origin); }
static JVMFlag::Error uintxAtPut (JVMFlag* f, uintx* v, JVMFlag::Flags origin) { return set<JVM_FLAG_TYPE(uintx)> (f, v, origin); }
static JVMFlag::Error uint64_tAtPut(JVMFlag* f, uint64_t* v, JVMFlag::Flags origin) { return set<JVM_FLAG_TYPE(uint64_t)>(f, v, origin); }
static JVMFlag::Error size_tAtPut (JVMFlag* f, size_t* v, JVMFlag::Flags origin) { return set<JVM_FLAG_TYPE(size_t)> (f, v, origin); }
static JVMFlag::Error doubleAtPut (JVMFlag* f, double* v, JVMFlag::Flags origin) { return set<JVM_FLAG_TYPE(double)> (f, v, origin); }
// Special handling needed for ccstr
// Contract: JVMFlag will make private copy of the incoming value.
// Outgoing value is always malloc-ed, and caller MUST call free.
static JVMFlag::Error ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlag::Flags origin);
// Handy aliases
static JVMFlag::Error ccstrAt(const JVMFlag* flag, ccstr* value) {
return get<ccstr, JVMFlag::TYPE_ccstr>(flag, value);
}
};
#endif // SHARE_RUNTIME_FLAGS_JVMFLAGACCESS_HPP

View file

@ -1,227 +0,0 @@
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
#include "gc/shared/jvmFlagConstraintsGC.hpp"
#include "runtime/arguments.hpp"
#include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagConstraintList.hpp"
#include "runtime/flags/jvmFlagConstraintsCompiler.hpp"
#include "runtime/flags/jvmFlagConstraintsRuntime.hpp"
#include "runtime/globals.hpp"
#include "runtime/globals_extension.hpp"
#include "runtime/os.hpp"
#include "utilities/macros.hpp"
class JVMFlagConstraint_bool : public JVMFlagConstraint {
JVMFlagConstraintFunc_bool _constraint;
public:
JVMFlagConstraint_bool(const JVMFlag* flag,
JVMFlagConstraintFunc_bool func,
ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
JVMFlag::Error apply(bool verbose) {
return _constraint(_flag->get_bool(), verbose);
}
JVMFlag::Error apply_bool(bool value, bool verbose) {
return _constraint(value, verbose);
}
};
class JVMFlagConstraint_int : public JVMFlagConstraint {
JVMFlagConstraintFunc_int _constraint;
public:
JVMFlagConstraint_int(const JVMFlag* flag,
JVMFlagConstraintFunc_int func,
ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
JVMFlag::Error apply(bool verbose) {
return _constraint(_flag->get_int(), verbose);
}
JVMFlag::Error apply_int(int value, bool verbose) {
return _constraint(value, verbose);
}
};
class JVMFlagConstraint_intx : public JVMFlagConstraint {
JVMFlagConstraintFunc_intx _constraint;
public:
JVMFlagConstraint_intx(const JVMFlag* flag,
JVMFlagConstraintFunc_intx func,
ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
JVMFlag::Error apply(bool verbose) {
return _constraint(_flag->get_intx(), verbose);
}
JVMFlag::Error apply_intx(intx value, bool verbose) {
return _constraint(value, verbose);
}
};
class JVMFlagConstraint_uint : public JVMFlagConstraint {
JVMFlagConstraintFunc_uint _constraint;
public:
JVMFlagConstraint_uint(const JVMFlag* flag,
JVMFlagConstraintFunc_uint func,
ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
JVMFlag::Error apply(bool verbose) {
return _constraint(_flag->get_uint(), verbose);
}
JVMFlag::Error apply_uint(uint value, bool verbose) {
return _constraint(value, verbose);
}
};
class JVMFlagConstraint_uintx : public JVMFlagConstraint {
JVMFlagConstraintFunc_uintx _constraint;
public:
JVMFlagConstraint_uintx(const JVMFlag* flag,
JVMFlagConstraintFunc_uintx func,
ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
JVMFlag::Error apply(bool verbose) {
return _constraint(_flag->get_uintx(), verbose);
}
JVMFlag::Error apply_uintx(uintx value, bool verbose) {
return _constraint(value, verbose);
}
};
class JVMFlagConstraint_uint64_t : public JVMFlagConstraint {
JVMFlagConstraintFunc_uint64_t _constraint;
public:
JVMFlagConstraint_uint64_t(const JVMFlag* flag,
JVMFlagConstraintFunc_uint64_t func,
ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
JVMFlag::Error apply(bool verbose) {
return _constraint(_flag->get_uint64_t(), verbose);
}
JVMFlag::Error apply_uint64_t(uint64_t value, bool verbose) {
return _constraint(value, verbose);
}
};
class JVMFlagConstraint_size_t : public JVMFlagConstraint {
JVMFlagConstraintFunc_size_t _constraint;
public:
JVMFlagConstraint_size_t(const JVMFlag* flag,
JVMFlagConstraintFunc_size_t func,
ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
JVMFlag::Error apply(bool verbose) {
return _constraint(_flag->get_size_t(), verbose);
}
JVMFlag::Error apply_size_t(size_t value, bool verbose) {
return _constraint(value, verbose);
}
};
class JVMFlagConstraint_double : public JVMFlagConstraint {
JVMFlagConstraintFunc_double _constraint;
public:
JVMFlagConstraint_double(const JVMFlag* flag,
JVMFlagConstraintFunc_double func,
ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
JVMFlag::Error apply(bool verbose) {
return _constraint(_flag->get_double(), verbose);
}
JVMFlag::Error apply_double(double value, bool verbose) {
return _constraint(value, verbose);
}
};
#define DEFINE_CONSTRAINT_APPLY(T) \
JVMFlag::Error JVMFlagConstraintChecker::apply_ ## T(T value, bool verbose) const { \
assert(exists(), "must be"); \
JVMFlagConstraint_ ## T constraint(_flag, \
(JVMFlagConstraintFunc_ ## T)_limit->constraint_func(), \
(JVMFlagConstraint::ConstraintType)_limit->phase()); \
return constraint.apply_ ## T(value, verbose); \
}
ALL_CONSTRAINT_TYPES(DEFINE_CONSTRAINT_APPLY)
JVMFlag::Error JVMFlagConstraintChecker::apply(bool verbose) const {
#define APPLY_CONSTRAINT(T) \
if (_flag->is_ ## T()) { \
JVMFlagConstraint_ ## T constraint(_flag, \
(JVMFlagConstraintFunc_ ## T)_limit->constraint_func(), \
(JVMFlagConstraint::ConstraintType)_limit->phase()); \
return constraint.apply(verbose); \
}
ALL_CONSTRAINT_TYPES(APPLY_CONSTRAINT);
ShouldNotReachHere();
return JVMFlag::INVALID_FLAG;
}
JVMFlagConstraint::ConstraintType JVMFlagConstraintList::_validating_type = JVMFlagConstraint::AtParse;
// Find constraints and return only if found constraint's type is equal or lower than current validating type.
JVMFlagConstraintChecker JVMFlagConstraintList::find_if_needs_check(const JVMFlag* flag) {
JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find(flag);
if (constraint.exists() && (constraint.type() <= _validating_type)) {
return constraint;
}
return JVMFlagConstraintChecker(flag, NULL);
}
// Check constraints for specific constraint type.
bool JVMFlagConstraintList::check_constraints(JVMFlagConstraint::ConstraintType type) {
guarantee(type > _validating_type, "Constraint check is out of order.");
_validating_type = type;
bool status = true;
for (int i = 0; i < NUM_JVMFlagsEnum; i++) {
JVMFlagConstraintChecker constraint(&JVMFlag::flags[i], JVMFlagLimit::get_constraint_at(i));
if (!constraint.exists()) continue;
if (type != constraint.type()) continue;
if (constraint.apply(true) != JVMFlag::SUCCESS) status = false;
}
return status;
}

View file

@ -1,113 +0,0 @@
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_RUNTIME_FLAGS_JVMFLAGCONSTRAINTLIST_HPP
#define SHARE_RUNTIME_FLAGS_JVMFLAGCONSTRAINTLIST_HPP
#include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagLimit.hpp"
/*
* Here we have a mechanism for extracting constraints (as custom functions) for flags,
* which otherwise can not be expressed via simple range check, specified in flag macro tables.
*
* An example of a constraint is "flag1 < flag2" where both flag1 and flag2 can change.
*
* See runtime "runtime/flags/jvmFlagConstraintsCompiler.hpp",
* "runtime/flags/jvmFlagConstraintsGC.hpp" and
* "runtime/flags/jvmFlagConstraintsRuntime.hpp" for the functions themselves.
*/
typedef JVMFlag::Error (*JVMFlagConstraintFunc_bool)(bool value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_int)(int value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_intx)(intx value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_uint)(uint value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_uintx)(uintx value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_uint64_t)(uint64_t value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_size_t)(size_t value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_double)(double value, bool verbose);
class JVMFlagConstraint : public CHeapObj<mtArguments> {
public:
// During VM initialization, constraint validation will be done order of ConstraintType.
enum ConstraintType {
// Will be validated during argument processing (Arguments::parse_argument).
AtParse = 0,
// Will be validated inside Threads::create_vm(), right after Arguments::apply_ergo().
AfterErgo = 1,
// Will be validated inside universe_init(), right after Metaspace::global_initialize().
AfterMemoryInit = 2
};
protected:
const JVMFlag* const _flag;
private:
ConstraintType _validate_type;
public:
// the "name" argument must be a string literal
JVMFlagConstraint(const JVMFlag* flag, ConstraintType type) : _flag(flag), _validate_type(type) {}
~JVMFlagConstraint() {}
const JVMFlag* flag() const { return _flag; }
ConstraintType type() const { return _validate_type; }
virtual JVMFlag::Error apply(bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
virtual JVMFlag::Error apply_bool(bool value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
virtual JVMFlag::Error apply_int(int value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
virtual JVMFlag::Error apply_intx(intx value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
virtual JVMFlag::Error apply_uint(uint value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
virtual JVMFlag::Error apply_uintx(uintx value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
virtual JVMFlag::Error apply_uint64_t(uint64_t value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
virtual JVMFlag::Error apply_size_t(size_t value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
virtual JVMFlag::Error apply_double(double value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
};
class JVMFlagConstraintChecker {
const JVMFlag* _flag;
const JVMFlagLimit* _limit;
public:
JVMFlagConstraintChecker(const JVMFlag* flag, const JVMFlagLimit* limit) : _flag(flag), _limit(limit) {}
bool exists() const { return _limit != NULL; }
JVMFlag::Error apply(bool verbose = true) const;
JVMFlagConstraint::ConstraintType type() const { return (JVMFlagConstraint::ConstraintType)_limit->phase(); }
#define DECLARE_CONSTRAINT_APPLY(T) JVMFlag::Error apply_ ## T(T new_value, bool verbose = true) const;
ALL_CONSTRAINT_TYPES(DECLARE_CONSTRAINT_APPLY)
};
class JVMFlagConstraintList : public AllStatic {
private:
// Latest constraint validation type.
static JVMFlagConstraint::ConstraintType _validating_type;
public:
static void init();
static JVMFlagConstraintChecker find(const JVMFlag* flag) { return JVMFlagConstraintChecker(flag, JVMFlagLimit::get_constraint(flag)); }
static JVMFlagConstraintChecker find_if_needs_check(const JVMFlag* flag);
// True if 'AfterErgo' or later constraint functions are validated.
static bool validated_after_ergo() { return _validating_type >= JVMFlagConstraint::AfterErgo; };
static bool check_constraints(JVMFlagConstraint::ConstraintType type);
};
#endif // SHARE_RUNTIME_FLAGS_JVMFLAGCONSTRAINTLIST_HPP

View file

@ -139,8 +139,8 @@ JVMFlag::Error VMPageSizeConstraintFunc(uintx value, bool verbose) {
JVMFlag::printError(verbose, JVMFlag::printError(verbose,
"%s %s=" UINTX_FORMAT " is outside the allowed range [ " UINTX_FORMAT "%s %s=" UINTX_FORMAT " is outside the allowed range [ " UINTX_FORMAT
" ... " UINTX_FORMAT " ]\n", " ... " UINTX_FORMAT " ]\n",
JVMFlagLimit::last_checked_flag()->_type, JVMFlagLimit::last_checked_flag()->type_string(),
JVMFlagLimit::last_checked_flag()->_name, JVMFlagLimit::last_checked_flag()->name(),
value, min, max_uintx); value, min, max_uintx);
return JVMFlag::VIOLATES_CONSTRAINT; return JVMFlag::VIOLATES_CONSTRAINT;
} }

View file

@ -26,11 +26,10 @@
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "gc/shared/jvmFlagConstraintsGC.hpp" #include "gc/shared/jvmFlagConstraintsGC.hpp"
#include "runtime/flags/jvmFlag.hpp" #include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagAccess.hpp"
#include "runtime/flags/jvmFlagLimit.hpp" #include "runtime/flags/jvmFlagLimit.hpp"
#include "runtime/flags/jvmFlagConstraintList.hpp"
#include "runtime/flags/jvmFlagConstraintsCompiler.hpp" #include "runtime/flags/jvmFlagConstraintsCompiler.hpp"
#include "runtime/flags/jvmFlagConstraintsRuntime.hpp" #include "runtime/flags/jvmFlagConstraintsRuntime.hpp"
#include "runtime/flags/jvmFlagRangeList.hpp"
#include "runtime/globals_extension.hpp" #include "runtime/globals_extension.hpp"
#include "gc/shared/referenceProcessor.hpp" #include "gc/shared/referenceProcessor.hpp"
#include "oops/markWord.hpp" #include "oops/markWord.hpp"
@ -98,7 +97,7 @@ public:
#define FLAG_LIMIT_PTR( type, name, ...) ), LimitGetter<type>::get_limit(&limit_##name, 0 #define FLAG_LIMIT_PTR( type, name, ...) ), LimitGetter<type>::get_limit(&limit_##name, 0
#define FLAG_LIMIT_PTR_NONE( type, name, ...) ), LimitGetter<type>::no_limit(0 #define FLAG_LIMIT_PTR_NONE( type, name, ...) ), LimitGetter<type>::no_limit(0
#define APPLY_FLAG_RANGE(...) , __VA_ARGS__ #define APPLY_FLAG_RANGE(...) , __VA_ARGS__
#define APPLY_FLAG_CONSTRAINT(func, phase) , next_two_args_are_constraint, (short)CONSTRAINT_ENUM(func), int(JVMFlagConstraint::phase) #define APPLY_FLAG_CONSTRAINT(func, phase) , next_two_args_are_constraint, (short)CONSTRAINT_ENUM(func), int(JVMFlagConstraintPhase::phase)
constexpr JVMTypedFlagLimit<int> limit_dummy constexpr JVMTypedFlagLimit<int> limit_dummy
( (
@ -145,6 +144,49 @@ static constexpr const JVMFlagLimit* const flagLimitTable[1 + NUM_JVMFlagsEnum]
) )
}; };
int JVMFlagLimit::_last_checked = -1; JVMFlagsEnum JVMFlagLimit::_last_checked = INVALID_JVMFlagsEnum;
JVMFlagConstraintPhase JVMFlagLimit::_validating_phase = JVMFlagConstraintPhase::AtParse;
const JVMFlagLimit* const* JVMFlagLimit::flagLimits = &flagLimitTable[1]; // excludes dummy const JVMFlagLimit* const* JVMFlagLimit::flagLimits = &flagLimitTable[1]; // excludes dummy
const JVMFlag* JVMFlagLimit::last_checked_flag() {
if (_last_checked != INVALID_JVMFlagsEnum) {
return JVMFlag::flag_from_enum(_last_checked);
} else {
return NULL;
}
}
bool JVMFlagLimit::check_all_ranges() {
bool status = true;
for (int i = 0; i < NUM_JVMFlagsEnum; i++) {
JVMFlagsEnum flag_enum = static_cast<JVMFlagsEnum>(i);
if (get_range_at(flag_enum) != NULL &&
JVMFlagAccess::check_range(JVMFlag::flag_from_enum(flag_enum), true) != JVMFlag::SUCCESS) {
status = false;
}
}
return status;
}
// Check constraints for specific constraint phase.
bool JVMFlagLimit::check_all_constraints(JVMFlagConstraintPhase phase) {
guarantee(phase > _validating_phase, "Constraint check is out of order.");
_validating_phase = phase;
bool status = true;
for (int i = 0; i < NUM_JVMFlagsEnum; i++) {
JVMFlagsEnum flag_enum = static_cast<JVMFlagsEnum>(i);
const JVMFlagLimit* constraint = get_constraint_at(flag_enum);
if (constraint != NULL && constraint->phase() == static_cast<int>(phase) &&
JVMFlagAccess::check_constraint(JVMFlag::flag_from_enum(flag_enum),
constraint->constraint_func(), true) != JVMFlag::SUCCESS) {
status = false;
}
}
return status;
}
void JVMFlagLimit::print_range(outputStream* st, const JVMFlag* flag) const {
JVMFlagAccess::print_range(st, flag, this);
}

View file

@ -27,20 +27,27 @@
#include "runtime/flags/jvmFlag.hpp" #include "runtime/flags/jvmFlag.hpp"
#define ALL_LIMIT_TYPES(f) \ class outputStream;
f(int) \
f(intx) \
f(uint) \
f(uintx) \
f(uint64_t) \
f(size_t) \
f(double)
#define ALL_RANGE_TYPES(f) ALL_LIMIT_TYPES(f)
#define ALL_CONSTRAINT_TYPES(f) ALL_LIMIT_TYPES(f) f(bool)
template <typename T> class JVMTypedFlagLimit; template <typename T> class JVMTypedFlagLimit;
enum class JVMFlagConstraintPhase : int {
// Will be validated during argument processing (Arguments::parse_argument).
AtParse = 0,
// Will be validated inside Threads::create_vm(), right after Arguments::apply_ergo().
AfterErgo = 1,
// Will be validated inside universe_init(), right after Metaspace::global_initialize().
AfterMemoryInit = 2
};
typedef JVMFlag::Error (*JVMFlagConstraintFunc_bool)(bool value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_int)(int value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_intx)(intx value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_uint)(uint value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_uintx)(uintx value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_uint64_t)(uint64_t value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_size_t)(size_t value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_double)(double value, bool verbose);
// A JVMFlagLimit is created for each JVMFlag that has a range() and/or constraint() in its declaration in // A JVMFlagLimit is created for each JVMFlag that has a range() and/or constraint() in its declaration in
// the globals_xxx.hpp file. // the globals_xxx.hpp file.
@ -61,14 +68,15 @@ class JVMFlagLimit {
char _kind; char _kind;
static const JVMFlagLimit* const* flagLimits; static const JVMFlagLimit* const* flagLimits;
static int _last_checked; static JVMFlagsEnum _last_checked;
static JVMFlagConstraintPhase _validating_phase;
protected: protected:
static constexpr int HAS_RANGE = 1; static constexpr int HAS_RANGE = 1;
static constexpr int HAS_CONSTRAINT = 2; static constexpr int HAS_CONSTRAINT = 2;
private: private:
static const JVMFlagLimit* get_kind_at(int flag_enum, int required_kind) { static const JVMFlagLimit* get_kind_at(JVMFlagsEnum flag_enum, int required_kind) {
const JVMFlagLimit* limit = at(flag_enum); const JVMFlagLimit* limit = at(flag_enum);
if (limit != NULL && (limit->_kind & required_kind) != 0) { if (limit != NULL && (limit->_kind & required_kind) != 0) {
_last_checked = flag_enum; _last_checked = flag_enum;
@ -78,9 +86,9 @@ private:
} }
} }
static const JVMFlagLimit* at(int flag_enum) { static const JVMFlagLimit* at(JVMFlagsEnum flag_enum) {
JVMFlag::assert_valid_flag_enum(flag_enum); JVMFlag::assert_valid_flag_enum(flag_enum);
return flagLimits[flag_enum]; return flagLimits[static_cast<int>(flag_enum)];
} }
public: public:
@ -93,28 +101,34 @@ public:
static const JVMFlagLimit* get_range(const JVMFlag* flag) { static const JVMFlagLimit* get_range(const JVMFlag* flag) {
return get_range_at(flag->flag_enum()); return get_range_at(flag->flag_enum());
} }
static const JVMFlagLimit* get_range_at(int flag_enum) { static const JVMFlagLimit* get_range_at(JVMFlagsEnum flag_enum) {
return get_kind_at(flag_enum, HAS_RANGE); return get_kind_at(flag_enum, HAS_RANGE);
} }
static const JVMFlagLimit* get_constraint(const JVMFlag* flag) { static const JVMFlagLimit* get_constraint(const JVMFlag* flag) {
return get_constraint_at(flag->flag_enum()); return get_constraint_at(flag->flag_enum());
} }
static const JVMFlagLimit* get_constraint_at(int flag_enum) { static const JVMFlagLimit* get_constraint_at(JVMFlagsEnum flag_enum) {
return get_kind_at(flag_enum, HAS_CONSTRAINT); return get_kind_at(flag_enum, HAS_CONSTRAINT);
} }
static const JVMFlag* last_checked_flag() { static const JVMFlag* last_checked_flag();
if (_last_checked >= 0) {
return JVMFlag::flag_from_enum(_last_checked); // Is the current value of each JVM flag within the allowed range (if specified)
} else { static bool check_all_ranges();
return NULL; void print_range(outputStream* st, const JVMFlag* flag) const;
}
// Does the current value of each JVM flag satisfy the specified constraint
static bool check_all_constraints(JVMFlagConstraintPhase phase);
// If range/constraint checks fail, print verbose error messages only if we are parsing
// arguments from the command-line. Silently ignore any invalid values that are
// set programmatically via FLAG_SET_ERGO, etc.
static bool verbose_checks_needed() {
return _validating_phase == JVMFlagConstraintPhase::AtParse;
} }
#define AS_TYPED_LIMIT(type) inline JVMTypedFlagLimit<type>* as_ ## type() const { return (JVMTypedFlagLimit<type>*)this; } static JVMFlagConstraintPhase validating_phase() { return _validating_phase; }
ALL_RANGE_TYPES(AS_TYPED_LIMIT)
}; };
enum ConstraintMarker { enum ConstraintMarker {

View file

@ -59,10 +59,10 @@ JVMFlag* JVMFlagLookup::find_impl(const char* name, size_t length) const {
for (int flag_enum = _buckets[bucket_index]; flag_enum >= 0; ) { for (int flag_enum = _buckets[bucket_index]; flag_enum >= 0; ) {
if (_hashes[flag_enum] == hash) { if (_hashes[flag_enum] == hash) {
JVMFlag* flag = JVMFlag::flags + flag_enum; JVMFlag* flag = JVMFlag::flags + flag_enum;
if (strncmp(name, flag->_name, length) == 0) { if (strncmp(name, flag->name(), length) == 0) {
// We know flag->_name has at least <length> bytes. // We know flag->name() has at least <length> bytes.
// Make sure it has exactly <length> bytes // Make sure it has exactly <length> bytes
if (flag->_name[length] == 0) { if (flag->name()[length] == 0) {
return flag; return flag;
} }
} }

View file

@ -1,321 +0,0 @@
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "jvm.h"
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
#include "gc/shared/referenceProcessor.hpp"
#include "oops/markWord.hpp"
#include "runtime/arguments.hpp"
#include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagConstraintList.hpp"
#include "runtime/flags/jvmFlagConstraintsRuntime.hpp"
#include "runtime/flags/jvmFlagRangeList.hpp"
#include "runtime/globals.hpp"
#include "runtime/globals_extension.hpp"
#include "runtime/os.hpp"
#include "runtime/task.hpp"
#include "utilities/macros.hpp"
class JVMFlagRange_int : public JVMFlagRange {
int _min;
int _max;
public:
JVMFlagRange_int(const JVMFlag* flag, int min, int max)
: JVMFlagRange(flag), _min(min), _max(max) {}
JVMFlag::Error check(bool verbose = true) {
return check_int(_flag->get_int(), verbose);
}
JVMFlag::Error check_int(int value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
JVMFlag::printError(verbose,
"int %s=%d is outside the allowed range "
"[ %d ... %d ]\n",
name(), value, _min, _max);
return JVMFlag::OUT_OF_BOUNDS;
} else {
return JVMFlag::SUCCESS;
}
}
void print(outputStream* st) {
st->print("[ %-25d ... %25d ]", _min, _max);
}
};
class JVMFlagRange_intx : public JVMFlagRange {
intx _min;
intx _max;
public:
JVMFlagRange_intx(const JVMFlag* flag, intx min, intx max)
: JVMFlagRange(flag), _min(min), _max(max) {}
JVMFlag::Error check(bool verbose = true) {
return check_intx(_flag->get_intx(), verbose);
}
JVMFlag::Error check_intx(intx value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
JVMFlag::printError(verbose,
"intx %s=" INTX_FORMAT " is outside the allowed range "
"[ " INTX_FORMAT " ... " INTX_FORMAT " ]\n",
name(), value, _min, _max);
return JVMFlag::OUT_OF_BOUNDS;
} else {
return JVMFlag::SUCCESS;
}
}
void print(outputStream* st) {
st->print("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", _min, _max);
}
};
class JVMFlagRange_uint : public JVMFlagRange {
uint _min;
uint _max;
public:
JVMFlagRange_uint(const JVMFlag* flag, uint min, uint max)
: JVMFlagRange(flag), _min(min), _max(max) {}
JVMFlag::Error check(bool verbose = true) {
return check_uint(_flag->get_uint(), verbose);
}
JVMFlag::Error check_uint(uint value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
JVMFlag::printError(verbose,
"uint %s=%u is outside the allowed range "
"[ %u ... %u ]\n",
name(), value, _min, _max);
return JVMFlag::OUT_OF_BOUNDS;
} else {
return JVMFlag::SUCCESS;
}
}
void print(outputStream* st) {
st->print("[ %-25u ... %25u ]", _min, _max);
}
};
class JVMFlagRange_uintx : public JVMFlagRange {
uintx _min;
uintx _max;
public:
JVMFlagRange_uintx(const JVMFlag* flag, uintx min, uintx max)
: JVMFlagRange(flag), _min(min), _max(max) {}
JVMFlag::Error check(bool verbose = true) {
return check_uintx(_flag->get_uintx(), verbose);
}
JVMFlag::Error check_uintx(uintx value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
JVMFlag::printError(verbose,
"uintx %s=" UINTX_FORMAT " is outside the allowed range "
"[ " UINTX_FORMAT " ... " UINTX_FORMAT " ]\n",
name(), value, _min, _max);
return JVMFlag::OUT_OF_BOUNDS;
} else {
return JVMFlag::SUCCESS;
}
}
void print(outputStream* st) {
st->print("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", _min, _max);
}
};
class JVMFlagRange_uint64_t : public JVMFlagRange {
uint64_t _min;
uint64_t _max;
public:
JVMFlagRange_uint64_t(const JVMFlag* flag, uint64_t min, uint64_t max)
: JVMFlagRange(flag), _min(min), _max(max) {}
JVMFlag::Error check(bool verbose = true) {
return check_uint64_t(_flag->get_uintx(), verbose);
}
JVMFlag::Error check_uint64_t(uint64_t value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
JVMFlag::printError(verbose,
"uint64_t %s=" UINT64_FORMAT " is outside the allowed range "
"[ " UINT64_FORMAT " ... " UINT64_FORMAT " ]\n",
name(), value, _min, _max);
return JVMFlag::OUT_OF_BOUNDS;
} else {
return JVMFlag::SUCCESS;
}
}
void print(outputStream* st) {
st->print("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", _min, _max);
}
};
class JVMFlagRange_size_t : public JVMFlagRange {
size_t _min;
size_t _max;
public:
JVMFlagRange_size_t(const JVMFlag* flag, size_t min, size_t max)
: JVMFlagRange(flag), _min(min), _max(max) {}
JVMFlag::Error check(bool verbose = true) {
return check_size_t(_flag->get_size_t(), verbose);
}
JVMFlag::Error check_size_t(size_t value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
JVMFlag::printError(verbose,
"size_t %s=" SIZE_FORMAT " is outside the allowed range "
"[ " SIZE_FORMAT " ... " SIZE_FORMAT " ]\n",
name(), value, _min, _max);
return JVMFlag::OUT_OF_BOUNDS;
} else {
return JVMFlag::SUCCESS;
}
}
void print(outputStream* st) {
st->print("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", _min, _max);
}
};
class JVMFlagRange_double : public JVMFlagRange {
double _min;
double _max;
public:
JVMFlagRange_double(const JVMFlag* flag, double min, double max)
: JVMFlagRange(flag), _min(min), _max(max) {}
JVMFlag::Error check(bool verbose = true) {
return check_double(_flag->get_double(), verbose);
}
JVMFlag::Error check_double(double value, bool verbose = true) {
if ((value < _min) || (value > _max)) {
JVMFlag::printError(verbose,
"double %s=%f is outside the allowed range "
"[ %f ... %f ]\n",
name(), value, _min, _max);
return JVMFlag::OUT_OF_BOUNDS;
} else {
return JVMFlag::SUCCESS;
}
}
void print(outputStream* st) {
st->print("[ %-25.3f ... %25.3f ]", _min, _max);
}
};
#define DEFINE_RANGE_CHECK(T) \
JVMFlag::Error JVMFlagRangeChecker::check_ ## T(T value, bool verbose) const { \
assert(exists(), "must be"); \
JVMFlagRange_ ## T range(_flag, _limit->as_ ## T()->min(), _limit->as_ ## T()->max()); \
return range.check_ ## T(value, verbose); \
}
ALL_RANGE_TYPES(DEFINE_RANGE_CHECK)
JVMFlag::Error JVMFlagRangeChecker::check(bool verbose) const {
#define CHECK_RANGE(T) \
if (_flag->is_ ## T()) { \
JVMFlagRange_ ## T range(_flag, _limit->as_ ## T()->min(), _limit->as_ ## T()->max()); \
return range.check(verbose); \
}
ALL_RANGE_TYPES(CHECK_RANGE);
ShouldNotReachHere();
return JVMFlag::INVALID_FLAG;
}
void JVMFlagRangeChecker::print(outputStream* out) const {
#define PRINT_RANGE(T) \
if (_flag->is_ ## T()) { \
JVMFlagRange_ ## T range(_flag, _limit->as_ ## T()->min(), _limit->as_ ## T()->max()); \
range.print(out); \
return; \
}
ALL_RANGE_TYPES(PRINT_RANGE);
ShouldNotReachHere();
}
void JVMFlagRangeList::print(outputStream* st, const JVMFlag* flag, RangeStrFunc default_range_str_func) {
JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
if (range.exists()) {
range.print(st);
} else {
const JVMFlagLimit* limit = JVMFlagLimit::get_constraint(flag);
if (limit != NULL) {
void* func = limit->constraint_func();
// Two special cases where the lower limit of the range is defined by an os:: function call
// and cannot be initialized at compile time with constexpr.
if (func == (void*)VMPageSizeConstraintFunc) {
uintx min = (uintx)os::vm_page_size();
uintx max = max_uintx;
JVMFlagRange_uintx tmp(flag, min, max);
tmp.print(st);
} else if (func == (void*)NUMAInterleaveGranularityConstraintFunc) {
size_t min = os::vm_allocation_granularity();
size_t max = NOT_LP64(2*G) LP64_ONLY(8192*G);
JVMFlagRange_size_t tmp(flag, min, max);
tmp.print(st);
} else {
assert(default_range_str_func!=NULL, "default_range_str_func must be provided");
st->print("%s", default_range_str_func());
}
} else {
st->print("[ ... ]");
}
}
}
bool JVMFlagRangeList::check_ranges() {
bool status = true;
for (int i = 0; i < NUM_JVMFlagsEnum; i++) {
JVMFlagRangeChecker range(&JVMFlag::flags[i], JVMFlagLimit::get_range_at(i));
if (range.exists() && range.check(true) != JVMFlag::SUCCESS) status = false;
}
return status;
}

View file

@ -1,83 +0,0 @@
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_RUNTIME_FLAGS_JVMFLAGRANGELIST_HPP
#define SHARE_RUNTIME_FLAGS_JVMFLAGRANGELIST_HPP
#include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagLimit.hpp"
/*
* Here we have a mechanism for extracting ranges specified in flag macro tables.
*
* The specified ranges are used to verify that flags have valid values.
*
* An example of a range is "min <= flag <= max". Both "min" and "max" must be
* constant and can not change. If either "min" or "max" can change,
* then we need to use constraint instead.
*/
class JVMFlagRange : public CHeapObj<mtArguments> {
protected:
const JVMFlag* const _flag;
public:
// the "name" argument must be a string literal
JVMFlagRange(const JVMFlag* flag) : _flag(flag) {}
~JVMFlagRange() {}
const JVMFlag* flag() const { return _flag; }
const char* name() const { return _flag->_name; }
virtual JVMFlag::Error check(bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; }
virtual JVMFlag::Error check_int(int value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; }
virtual JVMFlag::Error check_intx(intx value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; }
virtual JVMFlag::Error check_uint(uint value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; }
virtual JVMFlag::Error check_uintx(uintx value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; }
virtual JVMFlag::Error check_uint64_t(uint64_t value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; }
virtual JVMFlag::Error check_size_t(size_t value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; }
virtual JVMFlag::Error check_double(double value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; }
virtual void print(outputStream* st) { ; }
};
class JVMFlagRangeChecker {
const JVMFlag* _flag;
const JVMFlagLimit* _limit;
public:
JVMFlagRangeChecker(const JVMFlag* flag, const JVMFlagLimit* limit) : _flag(flag), _limit(limit) {}
bool exists() const { return _limit != NULL; }
JVMFlag::Error check(bool verbose = true) const;
void print(outputStream* st) const;
#define DECLARE_RANGE_CHECK(T) JVMFlag::Error check_ ## T(T new_value, bool verbose = true) const;
ALL_RANGE_TYPES(DECLARE_RANGE_CHECK)
};
class JVMFlagRangeList : public AllStatic {
public:
static JVMFlagRangeChecker find(const JVMFlag* flag) { return JVMFlagRangeChecker(flag, JVMFlagLimit::get_range(flag)); }
static void print(outputStream* st, const JVMFlag* flag, RangeStrFunc default_range_str_func);
// Check the final values of all flags for ranges.
static bool check_ranges();
};
#endif // SHARE_RUNTIME_FLAGS_JVMFLAGRANGELIST_HPP

View file

@ -31,7 +31,6 @@
#include "runtime/globals.hpp" #include "runtime/globals.hpp"
#include "runtime/globals_extension.hpp" #include "runtime/globals_extension.hpp"
#include "runtime/globals_shared.hpp" #include "runtime/globals_shared.hpp"
#include "runtime/flags/jvmFlagConstraintList.hpp"
#include "runtime/os.hpp" #include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp" #include "runtime/sharedRuntime.hpp"
#include "utilities/defaultStream.hpp" #include "utilities/defaultStream.hpp"

View file

@ -101,10 +101,10 @@
// //
// range is a macro that will expand to min and max arguments for range // range is a macro that will expand to min and max arguments for range
// checking code if provided - see jvmFlagRangeList.hpp // checking code if provided - see jvmFlagLimit.hpp
// //
// constraint is a macro that will expand to custom function call // constraint is a macro that will expand to custom function call
// for constraint checking if provided - see jvmFlagConstraintList.hpp // for constraint checking if provided - see jvmFlagLimit.hpp
// Default and minimum StringTable and SymbolTable size values // Default and minimum StringTable and SymbolTable size values
// Must be powers of 2 // Must be powers of 2

View file

@ -26,6 +26,7 @@
#define SHARE_RUNTIME_GLOBALS_EXTENSION_HPP #define SHARE_RUNTIME_GLOBALS_EXTENSION_HPP
#include "runtime/flags/jvmFlag.hpp" #include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagAccess.hpp"
#include "runtime/globals.hpp" #include "runtime/globals.hpp"
#include "utilities/macros.hpp" #include "utilities/macros.hpp"
@ -34,81 +35,49 @@
#define FLAG_MEMBER_ENUM(name) Flag_##name##_enum #define FLAG_MEMBER_ENUM(name) Flag_##name##_enum
#define FLAG_MEMBER_ENUM_(name) FLAG_MEMBER_ENUM(name), #define FLAG_MEMBER_ENUM_(name) FLAG_MEMBER_ENUM(name),
#define FLAG_MEMBER_ENUM_PRODUCT(type, name, value, ...) FLAG_MEMBER_ENUM_(name) #define DEFINE_FLAG_MEMBER_ENUM(type, name, ...) FLAG_MEMBER_ENUM_(name)
#define FLAG_MEMBER_ENUM_PD_PRODUCT(type, name, ...) FLAG_MEMBER_ENUM_(name)
#define FLAG_MEMBER_ENUM_DEVELOP(type, name, value, ...) FLAG_MEMBER_ENUM_(name)
#define FLAG_MEMBER_ENUM_PD_DEVELOP(type, name, ...) FLAG_MEMBER_ENUM_(name)
#define FLAG_MEMBER_ENUM_NOTPRODUCT(type, name, value, ...) FLAG_MEMBER_ENUM_(name)
typedef enum : int { enum JVMFlagsEnum : int {
ALL_FLAGS(FLAG_MEMBER_ENUM_DEVELOP, INVALID_JVMFlagsEnum = -1,
FLAG_MEMBER_ENUM_PD_DEVELOP, ALL_FLAGS(DEFINE_FLAG_MEMBER_ENUM,
FLAG_MEMBER_ENUM_PRODUCT, DEFINE_FLAG_MEMBER_ENUM,
FLAG_MEMBER_ENUM_PD_PRODUCT, DEFINE_FLAG_MEMBER_ENUM,
FLAG_MEMBER_ENUM_NOTPRODUCT, DEFINE_FLAG_MEMBER_ENUM,
DEFINE_FLAG_MEMBER_ENUM,
IGNORE_RANGE, IGNORE_RANGE,
IGNORE_CONSTRAINT) IGNORE_CONSTRAINT)
NUM_JVMFlagsEnum NUM_JVMFlagsEnum
} JVMFlagsEnum;
// Can't put the following in JVMFlags because
// of a circular dependency on the enum definition.
class JVMFlagEx : JVMFlag {
public:
static JVMFlag::Error boolAtPut(JVMFlagsEnum flag, bool value, JVMFlag::Flags origin);
static JVMFlag::Error intAtPut(JVMFlagsEnum flag, int value, JVMFlag::Flags origin);
static JVMFlag::Error uintAtPut(JVMFlagsEnum flag, uint value, JVMFlag::Flags origin);
static JVMFlag::Error intxAtPut(JVMFlagsEnum flag, intx value, JVMFlag::Flags origin);
static JVMFlag::Error uintxAtPut(JVMFlagsEnum flag, uintx value, JVMFlag::Flags origin);
static JVMFlag::Error uint64_tAtPut(JVMFlagsEnum flag, uint64_t value, JVMFlag::Flags origin);
static JVMFlag::Error size_tAtPut(JVMFlagsEnum flag, size_t value, JVMFlag::Flags origin);
static JVMFlag::Error doubleAtPut(JVMFlagsEnum flag, double value, JVMFlag::Flags origin);
// Contract: Flag will make private copy of the incoming value
static JVMFlag::Error ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlag::Flags origin);
static JVMFlag::Error ccstrlistAtPut(JVMFlagsEnum flag, ccstr value, JVMFlag::Flags origin) {
return ccstrAtPut(flag, value, origin);
}
static bool is_default(JVMFlagsEnum flag);
static bool is_ergo(JVMFlagsEnum flag);
static bool is_cmdline(JVMFlagsEnum flag);
static bool is_jimage_resource(JVMFlagsEnum flag);
static void setOnCmdLine(JVMFlagsEnum flag);
static JVMFlag* flag_from_enum(JVMFlagsEnum flag);
}; };
// Construct set functions for all flags // Construct set functions for all flags
#define FLAG_MEMBER_SET(name) Flag_##name##_set #define FLAG_MEMBER_SETTER(name) Flag_##name##_set
#define FLAG_MEMBER_SET_(type, name) inline JVMFlag::Error FLAG_MEMBER_SET(name)(type value, JVMFlag::Flags origin) { return JVMFlagEx::type##AtPut(FLAG_MEMBER_ENUM(name), value, origin); } #define FLAG_MEMBER_SETTER_(type, name) \
inline JVMFlag::Error FLAG_MEMBER_SETTER(name)(type value, JVMFlag::Flags origin) { \
return JVMFlagAccess::set<JVM_FLAG_TYPE(type)>(FLAG_MEMBER_ENUM(name), value, origin); \
}
#define FLAG_MEMBER_SET_PRODUCT(type, name, value, ...) FLAG_MEMBER_SET_(type, name) #define DEFINE_FLAG_MEMBER_SETTER(type, name, ...) FLAG_MEMBER_SETTER_(type, name)
#define FLAG_MEMBER_SET_PD_PRODUCT(type, name, ...) FLAG_MEMBER_SET_(type, name)
#define FLAG_MEMBER_SET_DEVELOP(type, name, value, ...) FLAG_MEMBER_SET_(type, name)
#define FLAG_MEMBER_SET_PD_DEVELOP(type, name, ...) FLAG_MEMBER_SET_(type, name)
#define FLAG_MEMBER_SET_NOTPRODUCT(type, name, value, ...) FLAG_MEMBER_SET_(type, name)
ALL_FLAGS(FLAG_MEMBER_SET_DEVELOP, ALL_FLAGS(DEFINE_FLAG_MEMBER_SETTER,
FLAG_MEMBER_SET_PD_DEVELOP, DEFINE_FLAG_MEMBER_SETTER,
FLAG_MEMBER_SET_PRODUCT, DEFINE_FLAG_MEMBER_SETTER,
FLAG_MEMBER_SET_PD_PRODUCT, DEFINE_FLAG_MEMBER_SETTER,
FLAG_MEMBER_SET_NOTPRODUCT, DEFINE_FLAG_MEMBER_SETTER,
IGNORE_RANGE, IGNORE_RANGE,
IGNORE_CONSTRAINT) IGNORE_CONSTRAINT)
#define FLAG_IS_DEFAULT(name) (JVMFlagEx::is_default(FLAG_MEMBER_ENUM(name))) #define FLAG_IS_DEFAULT(name) (JVMFlag::is_default(FLAG_MEMBER_ENUM(name)))
#define FLAG_IS_ERGO(name) (JVMFlagEx::is_ergo(FLAG_MEMBER_ENUM(name))) #define FLAG_IS_ERGO(name) (JVMFlag::is_ergo(FLAG_MEMBER_ENUM(name)))
#define FLAG_IS_CMDLINE(name) (JVMFlagEx::is_cmdline(FLAG_MEMBER_ENUM(name))) #define FLAG_IS_CMDLINE(name) (JVMFlag::is_cmdline(FLAG_MEMBER_ENUM(name)))
#define FLAG_IS_JIMAGE_RESOURCE(name) (JVMFlagEx::is_jimage_resource(FLAG_MEMBER_ENUM(name))) #define FLAG_IS_JIMAGE_RESOURCE(name) (JVMFlag::is_jimage_resource(FLAG_MEMBER_ENUM(name)))
#define FLAG_SET_DEFAULT(name, value) ((name) = (value)) #define FLAG_SET_DEFAULT(name, value) ((name) = (value))
#define FLAG_SET_CMDLINE(name, value) (JVMFlagEx::setOnCmdLine(FLAG_MEMBER_ENUM(name)), \ #define FLAG_SET_CMDLINE(name, value) (JVMFlag::setOnCmdLine(FLAG_MEMBER_ENUM(name)), \
FLAG_MEMBER_SET(name)((value), JVMFlag::COMMAND_LINE)) FLAG_MEMBER_SETTER(name)((value), JVMFlag::COMMAND_LINE))
#define FLAG_SET_ERGO(name, value) (FLAG_MEMBER_SET(name)((value), JVMFlag::ERGONOMIC)) #define FLAG_SET_ERGO(name, value) (FLAG_MEMBER_SETTER(name)((value), JVMFlag::ERGONOMIC))
#define FLAG_SET_MGMT(name, value) (FLAG_MEMBER_SET(name)((value), JVMFlag::MANAGEMENT)) #define FLAG_SET_MGMT(name, value) (FLAG_MEMBER_SETTER(name)((value), JVMFlag::MANAGEMENT))
#define FLAG_SET_ERGO_IF_DEFAULT(name, value) \ #define FLAG_SET_ERGO_IF_DEFAULT(name, value) \
do { \ do { \

View file

@ -68,8 +68,7 @@
#include "runtime/atomic.hpp" #include "runtime/atomic.hpp"
#include "runtime/biasedLocking.hpp" #include "runtime/biasedLocking.hpp"
#include "runtime/fieldDescriptor.inline.hpp" #include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/flags/jvmFlagConstraintList.hpp" #include "runtime/flags/jvmFlagLimit.hpp"
#include "runtime/flags/jvmFlagRangeList.hpp"
#include "runtime/deoptimization.hpp" #include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp" #include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
@ -3828,12 +3827,12 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
if (ergo_result != JNI_OK) return ergo_result; if (ergo_result != JNI_OK) return ergo_result;
// Final check of all ranges after ergonomics which may change values. // Final check of all ranges after ergonomics which may change values.
if (!JVMFlagRangeList::check_ranges()) { if (!JVMFlagLimit::check_all_ranges()) {
return JNI_EINVAL; return JNI_EINVAL;
} }
// Final check of all 'AfterErgo' constraints after ergonomics which may change values. // Final check of all 'AfterErgo' constraints after ergonomics which may change values.
bool constraint_result = JVMFlagConstraintList::check_constraints(JVMFlagConstraint::AfterErgo); bool constraint_result = JVMFlagLimit::check_all_constraints(JVMFlagConstraintPhase::AfterErgo);
if (!constraint_result) { if (!constraint_result) {
return JNI_EINVAL; return JNI_EINVAL;
} }

View file

@ -1008,7 +1008,7 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
/* -XX flags */ \ /* -XX flags */ \
/*********************/ \ /*********************/ \
\ \
nonstatic_field(JVMFlag, _type, const char*) \ nonstatic_field(JVMFlag, _type, int) \
nonstatic_field(JVMFlag, _name, const char*) \ nonstatic_field(JVMFlag, _name, const char*) \
unchecked_nonstatic_field(JVMFlag, _addr, sizeof(void*)) /* NOTE: no type */ \ unchecked_nonstatic_field(JVMFlag, _addr, sizeof(void*)) /* NOTE: no type */ \
nonstatic_field(JVMFlag, _flags, JVMFlag::Flags) \ nonstatic_field(JVMFlag, _flags, JVMFlag::Flags) \

View file

@ -1408,7 +1408,7 @@ JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
} }
// Exclude the locked (experimental, diagnostic) flags // Exclude the locked (experimental, diagnostic) flags
if (flag->is_unlocked() || flag->is_unlocker()) { if (flag->is_unlocked() || flag->is_unlocker()) {
Handle s = java_lang_String::create_from_str(flag->_name, CHECK_NULL); Handle s = java_lang_String::create_from_str(flag->name(), CHECK_NULL);
flags_ah->obj_at_put(num_entries, s()); flags_ah->obj_at_put(num_entries, s());
num_entries++; num_entries++;
} }
@ -1432,7 +1432,7 @@ JVM_END
bool add_global_entry(Handle name, jmmVMGlobal *global, JVMFlag *flag, TRAPS) { bool add_global_entry(Handle name, jmmVMGlobal *global, JVMFlag *flag, TRAPS) {
Handle flag_name; Handle flag_name;
if (name() == NULL) { if (name() == NULL) {
flag_name = java_lang_String::create_from_str(flag->_name, CHECK_false); flag_name = java_lang_String::create_from_str(flag->name(), CHECK_false);
} else { } else {
flag_name = name; flag_name = name;
} }

View file

@ -27,7 +27,8 @@
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "runtime/arguments.hpp" #include "runtime/arguments.hpp"
#include "runtime/flags/jvmFlag.hpp" #include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagRangeList.hpp" #include "runtime/flags/jvmFlagAccess.hpp"
#include "runtime/flags/jvmFlagLimit.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
#include "runtime/jniHandles.hpp" #include "runtime/jniHandles.hpp"
#include "services/writeableFlags.hpp" #include "services/writeableFlags.hpp"
@ -39,12 +40,11 @@ static void buffer_concat(char* buffer, const char* src) {
} }
static void print_flag_error_message_bounds(const JVMFlag* flag, char* buffer) { static void print_flag_error_message_bounds(const JVMFlag* flag, char* buffer) {
JVMFlagRangeChecker range = JVMFlagRangeList::find(flag); if (JVMFlagLimit::get_range(flag) != NULL) {
if (range.exists()) {
buffer_concat(buffer, "must have value in range "); buffer_concat(buffer, "must have value in range ");
stringStream stream; stringStream stream;
range.print(&stream); JVMFlagAccess::print_range(&stream, flag);
const char* range_string = stream.as_string(); const char* range_string = stream.as_string();
size_t j = strlen(buffer); size_t j = strlen(buffer);
for (size_t i=0; j<TEMP_BUF_SIZE-1; i++) { for (size_t i=0; j<TEMP_BUF_SIZE-1; i++) {
@ -64,7 +64,7 @@ static void print_flag_error_message_if_needed(JVMFlag::Error error, const JVMFl
return; return;
} }
const char* name = flag->_name; const char* name = flag->name();
char buffer[TEMP_BUF_SIZE] = {'\0'}; char buffer[TEMP_BUF_SIZE] = {'\0'};
if ((error != JVMFlag::MISSING_NAME) && (name != NULL)) { if ((error != JVMFlag::MISSING_NAME) && (name != NULL)) {
buffer_concat(buffer, name); buffer_concat(buffer, name);
@ -109,7 +109,7 @@ JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, const char* arg,
JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, bool value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, bool value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlag::boolAtPut(flag, &value, origin); JVMFlag::Error err = JVMFlagAccess::boolAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg); print_flag_error_message_if_needed(err, flag, err_msg);
return err; return err;
} }
@ -127,7 +127,7 @@ JVMFlag::Error WriteableFlags::set_int_flag(const char* name, const char* arg, J
JVMFlag::Error WriteableFlags::set_int_flag(const char* name, int value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_int_flag(const char* name, int value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlag::intAtPut(flag, &value, origin); JVMFlag::Error err = JVMFlagAccess::intAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg); print_flag_error_message_if_needed(err, flag, err_msg);
return err; return err;
} }
@ -145,7 +145,7 @@ JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, const char* arg,
JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, uint value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, uint value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlag::uintAtPut(flag, &value, origin); JVMFlag::Error err = JVMFlagAccess::uintAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg); print_flag_error_message_if_needed(err, flag, err_msg);
return err; return err;
} }
@ -163,7 +163,7 @@ JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, const char* arg,
JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, intx value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, intx value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlag::intxAtPut(flag, &value, origin); JVMFlag::Error err = JVMFlagAccess::intxAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg); print_flag_error_message_if_needed(err, flag, err_msg);
return err; return err;
} }
@ -181,7 +181,7 @@ JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, const char* arg,
JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, uintx value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, uintx value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlag::uintxAtPut(flag, &value, origin); JVMFlag::Error err = JVMFlagAccess::uintxAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg); print_flag_error_message_if_needed(err, flag, err_msg);
return err; return err;
} }
@ -199,7 +199,7 @@ JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, const char* a
JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, uint64_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, uint64_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlag::uint64_tAtPut(flag, &value, origin); JVMFlag::Error err = JVMFlagAccess::uint64_tAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg); print_flag_error_message_if_needed(err, flag, err_msg);
return err; return err;
} }
@ -217,7 +217,7 @@ JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, const char* arg
JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, size_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, size_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlag::size_tAtPut(flag, &value, origin); JVMFlag::Error err = JVMFlagAccess::size_tAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg); print_flag_error_message_if_needed(err, flag, err_msg);
return err; return err;
} }
@ -235,7 +235,7 @@ JVMFlag::Error WriteableFlags::set_double_flag(const char* name, const char* arg
JVMFlag::Error WriteableFlags::set_double_flag(const char* name, double value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_double_flag(const char* name, double value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlag::doubleAtPut(flag, &value, origin); JVMFlag::Error err = JVMFlagAccess::doubleAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg); print_flag_error_message_if_needed(err, flag, err_msg);
return err; return err;
} }
@ -243,7 +243,7 @@ JVMFlag::Error WriteableFlags::set_double_flag(const char* name, double value, J
// set a string global flag using value from AttachOperation // set a string global flag using value from AttachOperation
JVMFlag::Error WriteableFlags::set_ccstr_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_ccstr_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlag::ccstrAtPut(flag, &value, origin); JVMFlag::Error err = JVMFlagAccess::ccstrAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg); print_flag_error_message_if_needed(err, flag, err_msg);
return err; return err;
} }
@ -300,23 +300,23 @@ JVMFlag::Error WriteableFlags::set_flag_from_char(JVMFlag* f, const void* value,
return JVMFlag::MISSING_VALUE; return JVMFlag::MISSING_VALUE;
} }
if (f->is_bool()) { if (f->is_bool()) {
return set_bool_flag(f->_name, flag_value, origin, err_msg); return set_bool_flag(f->name(), flag_value, origin, err_msg);
} else if (f->is_int()) { } else if (f->is_int()) {
return set_int_flag(f->_name, flag_value, origin, err_msg); return set_int_flag(f->name(), flag_value, origin, err_msg);
} else if (f->is_uint()) { } else if (f->is_uint()) {
return set_uint_flag(f->_name, flag_value, origin, err_msg); return set_uint_flag(f->name(), flag_value, origin, err_msg);
} else if (f->is_intx()) { } else if (f->is_intx()) {
return set_intx_flag(f->_name, flag_value, origin, err_msg); return set_intx_flag(f->name(), flag_value, origin, err_msg);
} else if (f->is_uintx()) { } else if (f->is_uintx()) {
return set_uintx_flag(f->_name, flag_value, origin, err_msg); return set_uintx_flag(f->name(), flag_value, origin, err_msg);
} else if (f->is_uint64_t()) { } else if (f->is_uint64_t()) {
return set_uint64_t_flag(f->_name, flag_value, origin, err_msg); return set_uint64_t_flag(f->name(), flag_value, origin, err_msg);
} else if (f->is_size_t()) { } else if (f->is_size_t()) {
return set_size_t_flag(f->_name, flag_value, origin, err_msg); return set_size_t_flag(f->name(), flag_value, origin, err_msg);
} else if (f->is_double()) { } else if (f->is_double()) {
return set_double_flag(f->_name, flag_value, origin, err_msg); return set_double_flag(f->name(), flag_value, origin, err_msg);
} else if (f->is_ccstr()) { } else if (f->is_ccstr()) {
return set_ccstr_flag(f->_name, flag_value, origin, err_msg); return set_ccstr_flag(f->name(), flag_value, origin, err_msg);
} else { } else {
ShouldNotReachHere(); ShouldNotReachHere();
} }
@ -329,28 +329,28 @@ JVMFlag::Error WriteableFlags::set_flag_from_jvalue(JVMFlag* f, const void* valu
jvalue new_value = *(jvalue*)value; jvalue new_value = *(jvalue*)value;
if (f->is_bool()) { if (f->is_bool()) {
bool bvalue = (new_value.z == JNI_TRUE ? true : false); bool bvalue = (new_value.z == JNI_TRUE ? true : false);
return set_bool_flag(f->_name, bvalue, origin, err_msg); return set_bool_flag(f->name(), bvalue, origin, err_msg);
} else if (f->is_int()) { } else if (f->is_int()) {
int ivalue = (int)new_value.j; int ivalue = (int)new_value.j;
return set_int_flag(f->_name, ivalue, origin, err_msg); return set_int_flag(f->name(), ivalue, origin, err_msg);
} else if (f->is_uint()) { } else if (f->is_uint()) {
uint uvalue = (uint)new_value.j; uint uvalue = (uint)new_value.j;
return set_uint_flag(f->_name, uvalue, origin, err_msg); return set_uint_flag(f->name(), uvalue, origin, err_msg);
} else if (f->is_intx()) { } else if (f->is_intx()) {
intx ivalue = (intx)new_value.j; intx ivalue = (intx)new_value.j;
return set_intx_flag(f->_name, ivalue, origin, err_msg); return set_intx_flag(f->name(), ivalue, origin, err_msg);
} else if (f->is_uintx()) { } else if (f->is_uintx()) {
uintx uvalue = (uintx)new_value.j; uintx uvalue = (uintx)new_value.j;
return set_uintx_flag(f->_name, uvalue, origin, err_msg); return set_uintx_flag(f->name(), uvalue, origin, err_msg);
} else if (f->is_uint64_t()) { } else if (f->is_uint64_t()) {
uint64_t uvalue = (uint64_t)new_value.j; uint64_t uvalue = (uint64_t)new_value.j;
return set_uint64_t_flag(f->_name, uvalue, origin, err_msg); return set_uint64_t_flag(f->name(), uvalue, origin, err_msg);
} else if (f->is_size_t()) { } else if (f->is_size_t()) {
size_t svalue = (size_t)new_value.j; size_t svalue = (size_t)new_value.j;
return set_size_t_flag(f->_name, svalue, origin, err_msg); return set_size_t_flag(f->name(), svalue, origin, err_msg);
} else if (f->is_double()) { } else if (f->is_double()) {
double dvalue = (double)new_value.d; double dvalue = (double)new_value.d;
return set_double_flag(f->_name, dvalue, origin, err_msg); return set_double_flag(f->name(), dvalue, origin, err_msg);
} else if (f->is_ccstr()) { } else if (f->is_ccstr()) {
oop str = JNIHandles::resolve_external_guard(new_value.l); oop str = JNIHandles::resolve_external_guard(new_value.l);
if (str == NULL) { if (str == NULL) {
@ -358,7 +358,7 @@ JVMFlag::Error WriteableFlags::set_flag_from_jvalue(JVMFlag* f, const void* valu
return JVMFlag::MISSING_VALUE; return JVMFlag::MISSING_VALUE;
} }
ccstr svalue = java_lang_String::as_utf8_string(str); ccstr svalue = java_lang_String::as_utf8_string(str);
JVMFlag::Error ret = WriteableFlags::set_ccstr_flag(f->_name, svalue, origin, err_msg); JVMFlag::Error ret = WriteableFlags::set_ccstr_flag(f->name(), svalue, origin, err_msg);
if (ret != JVMFlag::SUCCESS) { if (ret != JVMFlag::SUCCESS) {
FREE_C_HEAP_ARRAY(char, svalue); FREE_C_HEAP_ARRAY(char, svalue);
} }

View file

@ -1002,6 +1002,27 @@ public class VM {
return (Flag) flagsMap.get(name); return (Flag) flagsMap.get(name);
} }
private static final String cmdFlagTypes[] = {
"bool",
"int",
"uint",
"intx",
"uintx",
"uint64_t",
"size_t",
"double",
"ccstr",
"ccstrlist"
};
private String getFlagTypeAsString(int typeIndex) {
if (0 <= typeIndex && typeIndex < cmdFlagTypes.length) {
return cmdFlagTypes[typeIndex];
} else {
return "unknown";
}
}
private void readCommandLineFlags() { private void readCommandLineFlags() {
// get command line flags // get command line flags
TypeDataBase db = getTypeDataBase(); TypeDataBase db = getTypeDataBase();
@ -1011,8 +1032,7 @@ public class VM {
commandLineFlags = new Flag[numFlags - 1]; commandLineFlags = new Flag[numFlags - 1];
Address flagAddr = flagType.getAddressField("flags").getValue(); Address flagAddr = flagType.getAddressField("flags").getValue();
CIntField typeFld = new CIntField(flagType.getCIntegerField("_type"), 0);
AddressField typeFld = flagType.getAddressField("_type");
AddressField nameFld = flagType.getAddressField("_name"); AddressField nameFld = flagType.getAddressField("_name");
AddressField addrFld = flagType.getAddressField("_addr"); AddressField addrFld = flagType.getAddressField("_addr");
CIntField flagsFld = new CIntField(flagType.getCIntegerField("_flags"), 0); CIntField flagsFld = new CIntField(flagType.getCIntegerField("_flags"), 0);
@ -1021,7 +1041,8 @@ public class VM {
// NOTE: last flag contains null values. // NOTE: last flag contains null values.
for (int f = 0; f < numFlags - 1; f++) { for (int f = 0; f < numFlags - 1; f++) {
String type = CStringUtilities.getString(typeFld.getValue(flagAddr)); int typeIndex = (int)typeFld.getValue(flagAddr);
String type = getFlagTypeAsString(typeIndex);
String name = CStringUtilities.getString(nameFld.getValue(flagAddr)); String name = CStringUtilities.getString(nameFld.getValue(flagAddr));
Address addr = addrFld.getValue(flagAddr); Address addr = addrFld.getValue(flagAddr);
int flags = (int)flagsFld.getValue(flagAddr); int flags = (int)flagsFld.getValue(flagAddr);