8262328: Templatize JVMFlag boilerplate access methods

Reviewed-by: dholmes, gziemski
This commit is contained in:
Ioi Lam 2021-04-10 15:39:27 +00:00
parent c15680e742
commit 627ad9fe22
10 changed files with 199 additions and 239 deletions

View File

@ -190,7 +190,7 @@ bool JVMCIGlobals::enable_jvmci_product_mode(JVMFlagOrigin origin) {
bool value = true; bool value = true;
JVMFlag *jvmciEnableFlag = JVMFlag::find_flag("EnableJVMCIProduct"); JVMFlag *jvmciEnableFlag = JVMFlag::find_flag("EnableJVMCIProduct");
if (JVMFlagAccess::boolAtPut(jvmciEnableFlag, &value, origin) != JVMFlag::SUCCESS) { if (JVMFlagAccess::set_bool(jvmciEnableFlag, &value, origin) != JVMFlag::SUCCESS) {
return false; return false;
} }

View File

@ -1249,58 +1249,38 @@ WB_ENTRY(jobject, WB_GetBooleanVMFlag(JNIEnv* env, jobject o, jstring name))
return NULL; return NULL;
WB_END WB_END
WB_ENTRY(jobject, WB_GetIntVMFlag(JNIEnv* env, jobject o, jstring name)) template <typename T, int type_enum>
int result; jobject GetVMFlag_longBox(JNIEnv* env, JavaThread* thread, jstring name) {
if (GetVMFlag <JVM_FLAG_TYPE(int)> (thread, env, name, &result)) { T result;
if (GetVMFlag <T, type_enum> (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);
} }
return NULL; return NULL;
}
WB_ENTRY(jobject, WB_GetIntVMFlag(JNIEnv* env, jobject o, jstring name))
return GetVMFlag_longBox<JVM_FLAG_TYPE(int)>(env, thread, name);
WB_END 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; return GetVMFlag_longBox<JVM_FLAG_TYPE(uint)>(env, thread, name);
if (GetVMFlag <JVM_FLAG_TYPE(uint)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result);
}
return NULL;
WB_END 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; return GetVMFlag_longBox<JVM_FLAG_TYPE(intx)>(env, thread, name);
if (GetVMFlag <JVM_FLAG_TYPE(intx)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result);
}
return NULL;
WB_END 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; return GetVMFlag_longBox<JVM_FLAG_TYPE(uintx)>(env, thread, name);
if (GetVMFlag <JVM_FLAG_TYPE(uintx)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result);
}
return NULL;
WB_END 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; return GetVMFlag_longBox<JVM_FLAG_TYPE(uint64_t)>(env, thread, name);
if (GetVMFlag <JVM_FLAG_TYPE(uint64_t)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result);
}
return NULL;
WB_END 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; return GetVMFlag_longBox<JVM_FLAG_TYPE(size_t)>(env, thread, name);
if (GetVMFlag <JVM_FLAG_TYPE(size_t)> (thread, env, name, &result)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result);
}
return NULL;
WB_END WB_END
WB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name)) WB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name))

View File

@ -804,7 +804,7 @@ void Arguments::describe_range_error(ArgsRange errcode) {
} }
static bool set_bool_flag(JVMFlag* flag, bool value, JVMFlagOrigin origin) { static bool set_bool_flag(JVMFlag* flag, bool value, JVMFlagOrigin origin) {
if (JVMFlagAccess::boolAtPut(flag, &value, origin) == JVMFlag::SUCCESS) { if (JVMFlagAccess::set_bool(flag, &value, origin) == JVMFlag::SUCCESS) {
return true; return true;
} else { } else {
return false; return false;
@ -819,7 +819,7 @@ static bool set_fp_numeric_flag(JVMFlag* flag, char* value, JVMFlagOrigin origin
return false; return false;
} }
if (JVMFlagAccess::doubleAtPut(flag, &v, origin) == JVMFlag::SUCCESS) { if (JVMFlagAccess::set_double(flag, &v, origin) == JVMFlag::SUCCESS) {
return true; return true;
} }
return false; return false;
@ -851,35 +851,35 @@ static bool set_numeric_flag(JVMFlag* flag, char* value, JVMFlagOrigin origin) {
if (is_neg) { if (is_neg) {
int_v = -int_v; int_v = -int_v;
} }
return JVMFlagAccess::intAtPut(flag, &int_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::set_int(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 JVMFlagAccess::uintAtPut(flag, &uint_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::set_uint(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 JVMFlagAccess::intxAtPut(flag, &intx_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::set_intx(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 JVMFlagAccess::uintxAtPut(flag, &uintx_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::set_uintx(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 JVMFlagAccess::uint64_tAtPut(flag, &uint64_t_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::set_uint64_t(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 JVMFlagAccess::size_tAtPut(flag, &size_t_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::set_size_t(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 JVMFlagAccess::doubleAtPut(flag, &double_v, origin) == JVMFlag::SUCCESS; return JVMFlagAccess::set_double(flag, &double_v, origin) == JVMFlag::SUCCESS;
} else { } else {
return false; return false;
} }
} }
static bool set_string_flag(JVMFlag* flag, const char* value, JVMFlagOrigin origin) { static bool set_string_flag(JVMFlag* flag, const char* value, JVMFlagOrigin origin) {
if (JVMFlagAccess::ccstrAtPut(flag, &value, origin) != JVMFlag::SUCCESS) return false; if (JVMFlagAccess::set_ccstr(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;
@ -887,7 +887,7 @@ static bool set_string_flag(JVMFlag* flag, const char* value, JVMFlagOrigin orig
static bool append_to_string_flag(JVMFlag* flag, const char* new_value, JVMFlagOrigin origin) { static bool append_to_string_flag(JVMFlag* flag, const char* new_value, JVMFlagOrigin origin) {
const char* old_value = ""; const char* old_value = "";
if (JVMFlagAccess::ccstrAt(flag, &old_value) != JVMFlag::SUCCESS) return false; if (JVMFlagAccess::get_ccstr(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;
@ -904,7 +904,7 @@ static bool append_to_string_flag(JVMFlag* flag, const char* new_value, JVMFlagO
value = buf; value = buf;
free_this_too = buf; free_this_too = buf;
} }
(void) JVMFlagAccess::ccstrAtPut(flag, &value, origin); (void) JVMFlagAccess::set_ccstr(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.

View File

@ -561,6 +561,14 @@ constexpr JVMFlag flagTable_verify_constexpr[] = { MATERIALIZE_ALL_FLAGS };
JVMFlag* JVMFlag::flags = flagTable; JVMFlag* JVMFlag::flags = flagTable;
size_t JVMFlag::numFlags = (sizeof(flagTable) / sizeof(JVMFlag)); size_t JVMFlag::numFlags = (sizeof(flagTable) / sizeof(JVMFlag));
#define JVM_FLAG_TYPE_SIGNATURE(t) JVMFlag::type_signature<t>(),
const int JVMFlag::type_signatures[] = {
JVM_FLAG_NON_STRING_TYPES_DO(JVM_FLAG_TYPE_SIGNATURE)
JVMFlag::type_signature<ccstr>(),
JVMFlag::type_signature<ccstr>()
};
// Search the flag table for a named flag // Search the flag table for a named flag
JVMFlag* JVMFlag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) { JVMFlag* JVMFlag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) {
JVMFlag* flag = JVMFlagLookup::find(name, length); JVMFlag* flag = JVMFlagLookup::find(name, length);

View File

@ -194,8 +194,7 @@ public:
#define JVM_FLAG_TYPE_ACCESSOR(t) \ #define JVM_FLAG_TYPE_ACCESSOR(t) \
bool is_##t() const { return _type == TYPE_##t;} \ bool is_##t() const { return _type == TYPE_##t;} \
t get_##t() const { assert(is_##t(), "sanity"); return *((t*) _addr); } \ t get_##t() const { assert(is_##t(), "sanity"); return *((t*) _addr); }
void set_##t(t value) { assert(is_##t(), "sanity"); *((t*) _addr) = value; }
JVM_FLAG_NON_STRING_TYPES_DO(JVM_FLAG_TYPE_ACCESSOR) JVM_FLAG_NON_STRING_TYPES_DO(JVM_FLAG_TYPE_ACCESSOR)
@ -225,23 +224,15 @@ public:
int type() const { return _type; } int type() const { return _type; }
const char* name() const { return _name; } const char* name() const { return _name; }
void assert_type(int type_enum) const {
if (type_enum == JVMFlag::TYPE_ccstr) {
assert(is_ccstr(), "type check"); // ccstr or ccstrlist
} else {
assert(_type == type_enum, "type check");
}
}
// Do not use JVMFlag::read() or JVMFlag::write() directly unless you know // Do not use JVMFlag::read() or JVMFlag::write() directly unless you know
// what you're doing. Use FLAG_SET_XXX macros or JVMFlagAccess instead. // what you're doing. Use FLAG_SET_XXX macros or JVMFlagAccess instead.
template <typename T, int type_enum> T read() const { template <typename T> T read() const {
assert_type(type_enum); assert_compatible_type<T>(_type);
return *static_cast<T*>(_addr); return *static_cast<T*>(_addr);
} }
template <typename T, int type_enum> void write(T value) { template <typename T> void write(T value) {
assert_type(type_enum); assert_compatible_type<T>(_type);
*static_cast<T*>(_addr) = value; *static_cast<T*>(_addr) = value;
} }
@ -291,25 +282,37 @@ public:
static const char* flag_error_str(JVMFlag::Error error); static const char* flag_error_str(JVMFlag::Error error);
// type checking private:
#define CHECK_COMPATIBLE(type) \ // type checking - the following functions make sure you access *_addr as
case TYPE_##type: \ // the correct type <T>
assert(sizeof(T) == sizeof(type) && \
std::is_integral<T>::value == std::is_integral<type>::value && \
std::is_signed <T>::value == std::is_signed <type>::value, "must be"); \
break;
static void assert_valid_type_enum(int type_enum) {
assert(0 <= type_enum && type_enum < NUM_FLAG_TYPES, "sanity");
}
// The following computation is not universal, but should be correct
// for the limited number of types that can be stored inside a JVMFlag.
template <typename T>
static constexpr int type_signature() {
return int(sizeof(T)) |
(((std::is_integral<T>::value) ? 1 : 0) << 8) |
(((std::is_signed<T>::value) ? 1 : 0) << 9) |
(((std::is_pointer<T>::value) ? 1 : 0) << 10);
}
static const int type_signatures[];
public:
template <typename T> template <typename T>
static void assert_compatible_type(int type_enum) { static void assert_compatible_type(int type_enum) {
#ifndef PRODUCT assert(is_compatible_type<T>(type_enum), "must be");
switch (type_enum) {
JVM_FLAG_NON_STRING_TYPES_DO(CHECK_COMPATIBLE);
default: ShouldNotReachHere();
}
#endif
} }
#undef CHECK_COMPATIBLE template <typename T>
static bool is_compatible_type(int type_enum) {
assert_valid_type_enum(type_enum);
return type_signatures[type_enum] == type_signature<T>();
}
public: public:
static void printSetFlags(outputStream* out); static void printSetFlags(outputStream* out);

View File

@ -56,7 +56,7 @@ public:
virtual JVMFlag::Error check_constraint(const JVMFlag* flag, void * func, bool verbose) const { return JVMFlag::SUCCESS; } virtual JVMFlag::Error check_constraint(const JVMFlag* flag, void * func, bool verbose) const { return JVMFlag::SUCCESS; }
}; };
template <typename T, int type_enum, typename EVENT> template <typename T, typename EVENT>
class TypedFlagAccessImpl : public FlagAccessImpl { class TypedFlagAccessImpl : public FlagAccessImpl {
public: public:
@ -70,9 +70,9 @@ public:
} }
} }
T old_value = flag->read<T, type_enum>(); T old_value = flag->read<T>();
trace_flag_changed<T, EVENT>(flag, old_value, value, origin); trace_flag_changed<T, EVENT>(flag, old_value, value, origin);
flag->write<T, type_enum>(value); flag->write<T>(value);
*((T*)value_addr) = old_value; *((T*)value_addr) = old_value;
flag->set_origin(origin); flag->set_origin(origin);
@ -80,17 +80,17 @@ public:
} }
JVMFlag::Error check_constraint(const JVMFlag* flag, void * func, bool verbose) const { JVMFlag::Error check_constraint(const JVMFlag* flag, void * func, bool verbose) const {
return typed_check_constraint(func, flag->read<T, type_enum>(), verbose); return typed_check_constraint(func, flag->read<T>(), verbose);
} }
virtual JVMFlag::Error typed_check_constraint(void * func, T value, bool verbose) const = 0; virtual JVMFlag::Error typed_check_constraint(void * func, T value, bool verbose) const = 0;
}; };
class FlagAccessImpl_bool : public TypedFlagAccessImpl<JVM_FLAG_TYPE(bool), EventBooleanFlagChanged> { class FlagAccessImpl_bool : public TypedFlagAccessImpl<bool, EventBooleanFlagChanged> {
public: public:
JVMFlag::Error set_impl(JVMFlag* flag, void* value_addr, JVMFlagOrigin origin) const { JVMFlag::Error set_impl(JVMFlag* flag, void* value_addr, JVMFlagOrigin origin) const {
bool verbose = JVMFlagLimit::verbose_checks_needed(); bool verbose = JVMFlagLimit::verbose_checks_needed();
return TypedFlagAccessImpl<JVM_FLAG_TYPE(bool), EventBooleanFlagChanged> return TypedFlagAccessImpl<bool, EventBooleanFlagChanged>
::check_constraint_and_set(flag, value_addr, origin, verbose); ::check_constraint_and_set(flag, value_addr, origin, verbose);
} }
@ -99,8 +99,8 @@ public:
} }
}; };
template <typename T, int type_enum, typename EVENT> template <typename T, typename EVENT>
class RangedFlagAccessImpl : public TypedFlagAccessImpl<T, type_enum, EVENT> { class RangedFlagAccessImpl : public TypedFlagAccessImpl<T, EVENT> {
public: public:
virtual JVMFlag::Error set_impl(JVMFlag* flag, void* value_addr, JVMFlagOrigin origin) const { virtual JVMFlag::Error set_impl(JVMFlag* flag, void* value_addr, JVMFlagOrigin origin) const {
T value = *((T*)value_addr); T value = *((T*)value_addr);
@ -114,13 +114,13 @@ public:
} }
} }
return TypedFlagAccessImpl<T, type_enum, EVENT>::check_constraint_and_set(flag, value_addr, origin, verbose); return TypedFlagAccessImpl<T, EVENT>::check_constraint_and_set(flag, value_addr, origin, verbose);
} }
virtual JVMFlag::Error check_range(const JVMFlag* flag, bool verbose) const { virtual JVMFlag::Error check_range(const JVMFlag* flag, bool verbose) const {
const JVMTypedFlagLimit<T>* range = (const JVMTypedFlagLimit<T>*)JVMFlagLimit::get_range(flag); const JVMTypedFlagLimit<T>* range = (const JVMTypedFlagLimit<T>*)JVMFlagLimit::get_range(flag);
if (range != NULL) { if (range != NULL) {
T value = flag->read<T, type_enum>(); T value = flag->read<T>();
if ((value < range->min()) || (value > range->max())) { if ((value < range->min()) || (value > range->max())) {
range_error(flag->name(), value, range->min(), range->max(), verbose); range_error(flag->name(), value, range->min(), range->max(), verbose);
return JVMFlag::OUT_OF_BOUNDS; return JVMFlag::OUT_OF_BOUNDS;
@ -138,7 +138,7 @@ public:
virtual void print_range_impl(outputStream* st, T min, T max) 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> { class FlagAccessImpl_int : public RangedFlagAccessImpl<int, EventIntFlagChanged> {
public: public:
void range_error(const char* name, int value, int min, int max, bool verbose) const { void range_error(const char* name, int value, int min, int max, bool verbose) const {
JVMFlag::printError(verbose, JVMFlag::printError(verbose,
@ -157,7 +157,7 @@ public:
} }
}; };
class FlagAccessImpl_uint : public RangedFlagAccessImpl<JVM_FLAG_TYPE(uint), EventUnsignedIntFlagChanged> { class FlagAccessImpl_uint : public RangedFlagAccessImpl<uint, EventUnsignedIntFlagChanged> {
public: public:
void range_error(const char* name, uint value, uint min, uint max, bool verbose) const { void range_error(const char* name, uint value, uint min, uint max, bool verbose) const {
JVMFlag::printError(verbose, JVMFlag::printError(verbose,
@ -176,7 +176,7 @@ public:
} }
}; };
class FlagAccessImpl_intx : public RangedFlagAccessImpl<JVM_FLAG_TYPE(intx), EventLongFlagChanged> { class FlagAccessImpl_intx : public RangedFlagAccessImpl<intx, EventLongFlagChanged> {
public: public:
void range_error(const char* name, intx value, intx min, intx max, bool verbose) const { void range_error(const char* name, intx value, intx min, intx max, bool verbose) const {
JVMFlag::printError(verbose, JVMFlag::printError(verbose,
@ -195,7 +195,7 @@ public:
} }
}; };
class FlagAccessImpl_uintx : public RangedFlagAccessImpl<JVM_FLAG_TYPE(uintx), EventUnsignedLongFlagChanged> { class FlagAccessImpl_uintx : public RangedFlagAccessImpl<uintx, EventUnsignedLongFlagChanged> {
public: public:
void range_error(const char* name, uintx value, uintx min, uintx max, bool verbose) const { void range_error(const char* name, uintx value, uintx min, uintx max, bool verbose) const {
JVMFlag::printError(verbose, JVMFlag::printError(verbose,
@ -214,7 +214,7 @@ public:
} }
}; };
class FlagAccessImpl_uint64_t : public RangedFlagAccessImpl<JVM_FLAG_TYPE(uint64_t), EventUnsignedLongFlagChanged> { class FlagAccessImpl_uint64_t : public RangedFlagAccessImpl<uint64_t, EventUnsignedLongFlagChanged> {
public: public:
void range_error(const char* name, uint64_t value, uint64_t min, uint64_t max, bool verbose) const { void range_error(const char* name, uint64_t value, uint64_t min, uint64_t max, bool verbose) const {
JVMFlag::printError(verbose, JVMFlag::printError(verbose,
@ -233,7 +233,7 @@ public:
} }
}; };
class FlagAccessImpl_size_t : public RangedFlagAccessImpl<JVM_FLAG_TYPE(size_t), EventUnsignedLongFlagChanged> { class FlagAccessImpl_size_t : public RangedFlagAccessImpl<size_t, EventUnsignedLongFlagChanged> {
public: public:
void range_error(const char* name, size_t value, size_t min, size_t max, bool verbose) const { void range_error(const char* name, size_t value, size_t min, size_t max, bool verbose) const {
JVMFlag::printError(verbose, JVMFlag::printError(verbose,
@ -252,7 +252,7 @@ public:
} }
}; };
class FlagAccessImpl_double : public RangedFlagAccessImpl<JVM_FLAG_TYPE(double), EventDoubleFlagChanged> { class FlagAccessImpl_double : public RangedFlagAccessImpl<double, EventDoubleFlagChanged> {
public: public:
void range_error(const char* name, double value, double min, double max, bool verbose) const { void range_error(const char* name, double value, double min, double max, bool verbose) const {
JVMFlag::printError(verbose, JVMFlag::printError(verbose,
@ -292,22 +292,15 @@ inline const FlagAccessImpl* JVMFlagAccess::access_impl(const JVMFlag* flag) {
return flag_accesss[type]; return flag_accesss[type];
} }
// This is called by JVMFlagAccess::*AtPut() and JVMFlagAccess::set<...>(JVMFlag* flag, ...) JVMFlag::Error JVMFlagAccess::set_impl(JVMFlag* flag, void* value, JVMFlagOrigin origin) {
JVMFlag::Error JVMFlagAccess::set_impl(JVMFlag* flag, int type_enum, void* value, JVMFlagOrigin origin) { if (flag->is_ccstr()) {
if (type_enum == JVMFlag::TYPE_ccstr || type_enum == JVMFlag::TYPE_ccstrlist) { return set_ccstr(flag, (ccstr*)value, origin);
return ccstrAtPut(flag, (ccstr*)value, origin); } else {
}
if (flag == NULL) {
return JVMFlag::INVALID_FLAG;
}
if (flag->type() != type_enum) {
return JVMFlag::WRONG_FORMAT;
}
return access_impl(flag)->set(flag, value, origin); return access_impl(flag)->set(flag, value, origin);
}
} }
JVMFlag::Error JVMFlagAccess::ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlagOrigin origin) { JVMFlag::Error JVMFlagAccess::set_ccstr(JVMFlag* flag, ccstr* value, JVMFlagOrigin origin) {
if (flag == NULL) return JVMFlag::INVALID_FLAG; if (flag == NULL) return JVMFlag::INVALID_FLAG;
if (!flag->is_ccstr()) return JVMFlag::WRONG_FORMAT; if (!flag->is_ccstr()) return JVMFlag::WRONG_FORMAT;
ccstr old_value = flag->get_ccstr(); ccstr old_value = flag->get_ccstr();
@ -331,14 +324,14 @@ JVMFlag::Error JVMFlagAccess::ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlagOri
} }
// This is called by the FLAG_SET_XXX macros. // This is called by the FLAG_SET_XXX macros.
JVMFlag::Error JVMFlagAccess::set_impl(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlagOrigin origin) { JVMFlag::Error JVMFlagAccess::set_or_assert(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlagOrigin origin) {
JVMFlag* flag = JVMFlag::flag_from_enum(flag_enum); JVMFlag* flag = JVMFlag::flag_from_enum(flag_enum);
if (type_enum == JVMFlag::TYPE_ccstr || type_enum == JVMFlag::TYPE_ccstrlist) { if (type_enum == JVMFlag::TYPE_ccstr || type_enum == JVMFlag::TYPE_ccstrlist) {
assert(flag->is_ccstr(), "must be"); assert(flag->is_ccstr(), "must be");
return ccstrAtPut(flag, (ccstr*)value, origin); return set_ccstr(flag, (ccstr*)value, origin);
} else { } else {
assert(flag->type() == type_enum, "wrong flag type"); assert(flag->type() == type_enum, "wrong flag type");
return set_impl(flag, type_enum, value, origin); return set_impl(flag, value, origin);
} }
} }

View File

@ -39,10 +39,10 @@ class outputStream;
// JVMFlag* flag = JVMFlag::flag_from_enum(FLAG_MEMBER_ENUM(ObjectAlignmentInBytes)); // JVMFlag* flag = JVMFlag::flag_from_enum(FLAG_MEMBER_ENUM(ObjectAlignmentInBytes));
// //
// /* If you use a wrong type, a run-time assertion will happen */ // /* If you use a wrong type, a run-time assertion will happen */
// intx v = flag->read<JVM_FLAG_TYPE(intx)>(); // intx v = flag->read<intx>();
// //
// /* If you use a wrong type, or a NULL flag, an error code is returned */ // /* 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); // JVMFlag::Error err = JVMFlagAccess::get<JVM_FLAG_TYPE(intx)>(flag, &v, origin);
#define JVM_FLAG_TYPE(t) \ #define JVM_FLAG_TYPE(t) \
t, JVMFlag::TYPE_ ## t t, JVMFlag::TYPE_ ## t
@ -52,8 +52,21 @@ class outputStream;
// of setters are provided. See notes below on which one to use. // of setters are provided. See notes below on which one to use.
class JVMFlagAccess : AllStatic { class JVMFlagAccess : AllStatic {
inline static const FlagAccessImpl* access_impl(const JVMFlag* flag); inline static const FlagAccessImpl* access_impl(const JVMFlag* flag);
static JVMFlag::Error set_impl(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlagOrigin origin); static JVMFlag::Error set_impl(JVMFlag* flag, void* value, JVMFlagOrigin origin);
static JVMFlag::Error set_impl(JVMFlag* flag, int type_enum, void* value, JVMFlagOrigin origin); static JVMFlag::Error set_or_assert(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlagOrigin origin);
static bool is_correct_type(const JVMFlag* flag, int type_enum) {
if (type_enum == JVMFlag::TYPE_ccstr) {
if (!flag->is_ccstr()) { // ccstr or ccstrlist
return false;
}
} else {
if (flag->type() != type_enum) {
return false;
}
}
return true;
}
public: public:
static JVMFlag::Error check_range(const JVMFlag* flag, bool verbose); static JVMFlag::Error check_range(const JVMFlag* flag, bool verbose);
@ -63,19 +76,18 @@ public:
template <typename T, int type_enum> template <typename T, int type_enum>
static JVMFlag::Error get(const JVMFlag* flag, T* value) { static JVMFlag::Error get(const JVMFlag* flag, T* value) {
// The caller must not not mix incompatible types such as
// set<double, JVMFlag::TYPE_int>(flag, double_ptr);
assert(JVMFlag::is_compatible_type<T>(type_enum), "must be");
if (flag == NULL) { if (flag == NULL) {
return JVMFlag::INVALID_FLAG; return JVMFlag::INVALID_FLAG;
} }
if (type_enum == JVMFlag::TYPE_ccstr) { if (!is_correct_type(flag, type_enum)) {
if (!flag->is_ccstr()) { // ccstr or ccstrlist
return JVMFlag::WRONG_FORMAT; return JVMFlag::WRONG_FORMAT;
} }
} else {
if (flag->type() != type_enum) { *value = flag->read<T>();
return JVMFlag::WRONG_FORMAT;
}
}
*value = flag->read<T, type_enum>();
return JVMFlag::SUCCESS; return JVMFlag::SUCCESS;
} }
@ -85,37 +97,47 @@ public:
// type_enum will result in an assert. // type_enum will result in an assert.
template <typename T, int type_enum> template <typename T, int type_enum>
static JVMFlag::Error set(JVMFlagsEnum flag_enum, T value, JVMFlagOrigin origin) { static JVMFlag::Error set(JVMFlagsEnum flag_enum, T value, JVMFlagOrigin origin) {
return set_impl(flag_enum, type_enum, &value, origin); return set_or_assert(flag_enum, type_enum, &value, origin);
} }
// This setter, and the xxxAtPut functions below, are *generic* setters. They should be used // This is a *generic* setter. It should be used by code that can set a number of different
// by code that can set a number of different flags, often according to external input that // flags, often according to external input that may contain errors.
// may contain errors.
// Examples callers are arguments.cpp, writeableFlags.cpp, and WB_SetXxxVMFlag functions. // Examples callers are arguments.cpp, writeableFlags.cpp, and WB_SetXxxVMFlag functions.
// A mismatched type_enum would result in a JVMFlag::WRONG_FORMAT code. // A mismatched type_enum would result in a JVMFlag::WRONG_FORMAT code.
template <typename T, int type_enum> template <typename T, int type_enum>
static JVMFlag::Error set(JVMFlag* flag, T* value, JVMFlagOrigin origin) { static JVMFlag::Error set(JVMFlag* flag, T* value, JVMFlagOrigin origin) {
return set_impl(flag, type_enum, (void*)value, origin); // The caller must not not mix incompatible types such as
// set<double, JVMFlag::TYPE_int>(flag, double_ptr);
assert(JVMFlag::is_compatible_type<T>(type_enum), "must be");
if (flag == NULL) {
return JVMFlag::INVALID_FLAG;
}
if (!is_correct_type(flag, type_enum)) {
return JVMFlag::WRONG_FORMAT;
} }
static JVMFlag::Error boolAtPut (JVMFlag* f, bool* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(bool)> (f, v, origin); } return set_impl(flag, (void*)value, origin);
static JVMFlag::Error intAtPut (JVMFlag* f, int* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(int)> (f, v, origin); } }
static JVMFlag::Error uintAtPut (JVMFlag* f, uint* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uint)> (f, v, origin); }
static JVMFlag::Error intxAtPut (JVMFlag* f, intx* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(intx)> (f, v, origin); }
static JVMFlag::Error uintxAtPut (JVMFlag* f, uintx* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uintx)> (f, v, origin); }
static JVMFlag::Error uint64_tAtPut(JVMFlag* f, uint64_t* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uint64_t)>(f, v, origin); }
static JVMFlag::Error size_tAtPut (JVMFlag* f, size_t* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(size_t)> (f, v, origin); }
static JVMFlag::Error doubleAtPut (JVMFlag* f, double* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(double)> (f, v, origin); }
// Special handling needed for ccstr // Special handling needed for ccstr
// Contract: JVMFlag will make private copy of the incoming value. // Contract: JVMFlag will make private copy of the incoming value.
// Outgoing value is always malloc-ed, and caller MUST call free. // Outgoing value is always malloc-ed, and caller MUST call free.
static JVMFlag::Error ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlagOrigin origin); static JVMFlag::Error set_ccstr(JVMFlag* flag, ccstr* value, JVMFlagOrigin origin);
// Handy aliases // Handy aliases
static JVMFlag::Error ccstrAt(const JVMFlag* flag, ccstr* value) { static JVMFlag::Error get_ccstr(const JVMFlag* flag, ccstr* value) {
return get<ccstr, JVMFlag::TYPE_ccstr>(flag, value); return get<JVM_FLAG_TYPE(ccstr)>(flag, value);
} }
static JVMFlag::Error set_bool (JVMFlag* f, bool* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(bool)> (f, v, origin); }
static JVMFlag::Error set_int (JVMFlag* f, int* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(int)> (f, v, origin); }
static JVMFlag::Error set_uint (JVMFlag* f, uint* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uint)> (f, v, origin); }
static JVMFlag::Error set_intx (JVMFlag* f, intx* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(intx)> (f, v, origin); }
static JVMFlag::Error set_uintx (JVMFlag* f, uintx* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uintx)> (f, v, origin); }
static JVMFlag::Error set_uint64_t(JVMFlag* f, uint64_t* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uint64_t)>(f, v, origin); }
static JVMFlag::Error set_size_t (JVMFlag* f, size_t* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(size_t)> (f, v, origin); }
static JVMFlag::Error set_double (JVMFlag* f, double* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(double)> (f, v, origin); }
}; };
#endif // SHARE_RUNTIME_FLAGS_JVMFLAGACCESS_HPP #endif // SHARE_RUNTIME_FLAGS_JVMFLAGACCESS_HPP

View File

@ -96,154 +96,107 @@ static void print_flag_error_message_if_needed(JVMFlag::Error error, const JVMFl
err_msg.print("%s", buffer); err_msg.print("%s", buffer);
} }
template <typename T, int type_enum>
JVMFlag::Error WriteableFlags::set_flag_impl(const char* name, T value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlagAccess::set<T, type_enum>(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg);
return err;
}
// set a boolean global flag // set a boolean global flag
JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
if ((strcasecmp(arg, "true") == 0) || (*arg == '1' && *(arg + 1) == 0)) { if ((strcasecmp(arg, "true") == 0) || (*arg == '1' && *(arg + 1) == 0)) {
return set_bool_flag(name, true, origin, err_msg); return set_flag_impl<JVM_FLAG_TYPE(bool)>(name, true, origin, err_msg);
} else if ((strcasecmp(arg, "false") == 0) || (*arg == '0' && *(arg + 1) == 0)) { } else if ((strcasecmp(arg, "false") == 0) || (*arg == '0' && *(arg + 1) == 0)) {
return set_bool_flag(name, false, origin, err_msg); return set_flag_impl<JVM_FLAG_TYPE(bool)>(name, false, origin, err_msg);
} }
err_msg.print("flag value must be a boolean (1/0 or true/false)"); err_msg.print("flag value must be a boolean (1/0 or true/false)");
return JVMFlag::WRONG_FORMAT; return JVMFlag::WRONG_FORMAT;
} }
JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, bool value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlagAccess::boolAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg);
return err;
}
// set a int global flag // set a int global flag
JVMFlag::Error WriteableFlags::set_int_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_int_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
int value; int value;
if (sscanf(arg, "%d", &value) == 1) { if (sscanf(arg, "%d", &value) == 1) {
return set_int_flag(name, value, origin, err_msg); return set_flag_impl<JVM_FLAG_TYPE(int)>(name, value, origin, err_msg);
} }
err_msg.print("flag value must be an integer"); err_msg.print("flag value must be an integer");
return JVMFlag::WRONG_FORMAT; return JVMFlag::WRONG_FORMAT;
} }
JVMFlag::Error WriteableFlags::set_int_flag(const char* name, int value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlagAccess::intAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg);
return err;
}
// set a uint global flag // set a uint global flag
JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
uint value; uint value;
if (sscanf(arg, "%u", &value) == 1) { if (sscanf(arg, "%u", &value) == 1) {
return set_uint_flag(name, value, origin, err_msg); return set_flag_impl<JVM_FLAG_TYPE(uint)>(name, value, origin, err_msg);
} }
err_msg.print("flag value must be an unsigned integer"); err_msg.print("flag value must be an unsigned integer");
return JVMFlag::WRONG_FORMAT; return JVMFlag::WRONG_FORMAT;
} }
JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, uint value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlagAccess::uintAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg);
return err;
}
// set a intx global flag // set a intx global flag
JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
intx value; intx value;
if (sscanf(arg, INTX_FORMAT, &value) == 1) { if (sscanf(arg, INTX_FORMAT, &value) == 1) {
return set_intx_flag(name, value, origin, err_msg); return set_flag_impl<JVM_FLAG_TYPE(intx)>(name, value, origin, err_msg);
} }
err_msg.print("flag value must be an integer"); err_msg.print("flag value must be an integer");
return JVMFlag::WRONG_FORMAT; return JVMFlag::WRONG_FORMAT;
} }
JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, intx value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlagAccess::intxAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg);
return err;
}
// set a uintx global flag // set a uintx global flag
JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
uintx value; uintx value;
if (sscanf(arg, UINTX_FORMAT, &value) == 1) { if (sscanf(arg, UINTX_FORMAT, &value) == 1) {
return set_uintx_flag(name, value, origin, err_msg); return set_flag_impl<JVM_FLAG_TYPE(uintx)>(name, value, origin, err_msg);
} }
err_msg.print("flag value must be an unsigned integer"); err_msg.print("flag value must be an unsigned integer");
return JVMFlag::WRONG_FORMAT; return JVMFlag::WRONG_FORMAT;
} }
JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, uintx value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlagAccess::uintxAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg);
return err;
}
// set a uint64_t global flag // set a uint64_t global flag
JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
uint64_t value; uint64_t value;
if (sscanf(arg, UINT64_FORMAT, &value) == 1) { if (sscanf(arg, UINT64_FORMAT, &value) == 1) {
return set_uint64_t_flag(name, value, origin, err_msg); return set_flag_impl<JVM_FLAG_TYPE(uint64_t)>(name, value, origin, err_msg);
} }
err_msg.print("flag value must be an unsigned 64-bit integer"); err_msg.print("flag value must be an unsigned 64-bit integer");
return JVMFlag::WRONG_FORMAT; return JVMFlag::WRONG_FORMAT;
} }
JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, uint64_t value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlagAccess::uint64_tAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg);
return err;
}
// set a size_t global flag // set a size_t global flag
JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
size_t value; size_t value;
if (sscanf(arg, SIZE_FORMAT, &value) == 1) { if (sscanf(arg, SIZE_FORMAT, &value) == 1) {
return set_size_t_flag(name, value, origin, err_msg); return set_flag_impl<JVM_FLAG_TYPE(size_t)>(name, value, origin, err_msg);
} }
err_msg.print("flag value must be an unsigned integer"); err_msg.print("flag value must be an unsigned integer");
return JVMFlag::WRONG_FORMAT; return JVMFlag::WRONG_FORMAT;
} }
JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, size_t value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlagAccess::size_tAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg);
return err;
}
// set a double global flag // set a double global flag
JVMFlag::Error WriteableFlags::set_double_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_double_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
double value; double value;
if (sscanf(arg, "%lf", &value) == 1) { if (sscanf(arg, "%lf", &value) == 1) {
return set_double_flag(name, value, origin, err_msg); return set_flag_impl<JVM_FLAG_TYPE(double)>(name, value, origin, err_msg);
} }
err_msg.print("flag value must be a double"); err_msg.print("flag value must be a double");
return JVMFlag::WRONG_FORMAT; return JVMFlag::WRONG_FORMAT;
} }
JVMFlag::Error WriteableFlags::set_double_flag(const char* name, double value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlagAccess::doubleAtPut(flag, &value, origin);
print_flag_error_message_if_needed(err, flag, err_msg);
return err;
}
// 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, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag::Error WriteableFlags::set_ccstr_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) {
JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag* flag = JVMFlag::find_flag(name);
JVMFlag::Error err = JVMFlagAccess::ccstrAtPut(flag, &value, origin); JVMFlag::Error err = JVMFlagAccess::set_ccstr(flag, &value, origin);
if (err == JVMFlag::SUCCESS) { if (err == JVMFlag::SUCCESS) {
assert(value == NULL, "old value is freed automatically and not returned"); assert(value == NULL, "old value is freed automatically and not returned");
} }
@ -332,28 +285,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_flag_impl<JVM_FLAG_TYPE(bool)>(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_flag_impl<JVM_FLAG_TYPE(int)>(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_flag_impl<JVM_FLAG_TYPE(uint)>(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_flag_impl<JVM_FLAG_TYPE(intx)>(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_flag_impl<JVM_FLAG_TYPE(uintx)>(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_flag_impl<JVM_FLAG_TYPE(uint64_t)>(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_flag_impl<JVM_FLAG_TYPE(size_t)>(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_flag_impl<JVM_FLAG_TYPE(double)>(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) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -38,41 +38,19 @@ private:
// a writeable flag setter accepting 'jvalue' values // a writeable flag setter accepting 'jvalue' values
static JVMFlag::Error set_flag_from_jvalue(JVMFlag* f, const void* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); static JVMFlag::Error set_flag_from_jvalue(JVMFlag* f, const void* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a boolean global flag
static JVMFlag::Error set_bool_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); static JVMFlag::Error set_bool_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a int global flag
static JVMFlag::Error set_int_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); static JVMFlag::Error set_int_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a uint global flag
static JVMFlag::Error set_uint_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); static JVMFlag::Error set_uint_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a intx global flag
static JVMFlag::Error set_intx_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); static JVMFlag::Error set_intx_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a uintx global flag
static JVMFlag::Error set_uintx_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); static JVMFlag::Error set_uintx_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a uint64_t global flag
static JVMFlag::Error set_uint64_t_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); static JVMFlag::Error set_uint64_t_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a size_t global flag using value from AttachOperation
static JVMFlag::Error set_size_t_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); static JVMFlag::Error set_size_t_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a double global flag using value from AttachOperation
static JVMFlag::Error set_double_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); static JVMFlag::Error set_double_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a boolean global flag
static JVMFlag::Error set_bool_flag(const char* name, bool value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a int global flag
static JVMFlag::Error set_int_flag(const char* name, int value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a uint global flag
static JVMFlag::Error set_uint_flag(const char* name, uint value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a intx global flag
static JVMFlag::Error set_intx_flag(const char* name, intx value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a uintx global flag
static JVMFlag::Error set_uintx_flag(const char* name, uintx value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a uint64_t global flag
static JVMFlag::Error set_uint64_t_flag(const char* name, uint64_t value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a size_t global flag using value from AttachOperation
static JVMFlag::Error set_size_t_flag(const char* name, size_t value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a double global flag using value from AttachOperation
static JVMFlag::Error set_double_flag(const char* name, double value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
// set a string global flag
static JVMFlag::Error set_ccstr_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); static JVMFlag::Error set_ccstr_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
template <typename T, int type_enum>
static JVMFlag::Error set_flag_impl(const char* name, T value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg);
public: public:
/* sets a writeable flag to the provided value /* sets a writeable flag to the provided value
* *

View File

@ -28,6 +28,7 @@
#include "runtime/globals_extension.hpp" #include "runtime/globals_extension.hpp"
#include "runtime/flags/flagSetting.hpp" #include "runtime/flags/flagSetting.hpp"
#include "runtime/flags/jvmFlag.hpp" #include "runtime/flags/jvmFlag.hpp"
#include "runtime/flags/jvmFlagAccess.hpp"
#include "unittest.hpp" #include "unittest.hpp"
#define TEST_FLAG(f, type, value) \ #define TEST_FLAG(f, type, value) \
@ -94,3 +95,25 @@ TEST_VM(FlagAccess, ccstr_flag) {
ASSERT_EQ(FLAG_IS_ERGO(SharedArchiveConfigFile), true); ASSERT_EQ(FLAG_IS_ERGO(SharedArchiveConfigFile), true);
ASSERT_EQ(strcmp(SharedArchiveConfigFile, "xyz"), 0); ASSERT_EQ(strcmp(SharedArchiveConfigFile, "xyz"), 0);
} }
template <typename T, int type_enum>
static JVMFlag::Error get_flag(const char* name) {
JVMFlag* flag = (name == NULL) ? NULL : JVMFlag::find_flag(name);
T val;
return JVMFlagAccess::get<T, type_enum>(flag, &val);
}
TEST_VM(FlagAccess, wrong_format) {
ASSERT_EQ((get_flag<JVM_FLAG_TYPE(int)>(NULL)), JVMFlag::INVALID_FLAG);
// MaxRAMPercentage is a double flag
ASSERT_EQ((get_flag<JVM_FLAG_TYPE(bool)> ("MaxRAMPercentage")), JVMFlag::WRONG_FORMAT);
ASSERT_EQ((get_flag<JVM_FLAG_TYPE(int)> ("MaxRAMPercentage")), JVMFlag::WRONG_FORMAT);
ASSERT_EQ((get_flag<JVM_FLAG_TYPE(uint)> ("MaxRAMPercentage")), JVMFlag::WRONG_FORMAT);
ASSERT_EQ((get_flag<JVM_FLAG_TYPE(intx)> ("MaxRAMPercentage")), JVMFlag::WRONG_FORMAT);
ASSERT_EQ((get_flag<JVM_FLAG_TYPE(uintx)> ("MaxRAMPercentage")), JVMFlag::WRONG_FORMAT);
ASSERT_EQ((get_flag<JVM_FLAG_TYPE(uint64_t)>("MaxRAMPercentage")), JVMFlag::WRONG_FORMAT);
ASSERT_EQ((get_flag<JVM_FLAG_TYPE(size_t)> ("MaxRAMPercentage")), JVMFlag::WRONG_FORMAT);
ASSERT_EQ((get_flag<JVM_FLAG_TYPE(double)> ("MaxRAMPercentage")), JVMFlag::SUCCESS);
}