8255231: Avoid upcalls when initializing the statSampler
Reviewed-by: iklam, dholmes
This commit is contained in:
parent
dccfd2b3e0
commit
f7c59c661c
src
hotspot/share
java.base/share/classes/java/lang
@ -147,6 +147,7 @@
|
||||
\
|
||||
/* Java runtime version access */ \
|
||||
template(java_lang_VersionProps, "java/lang/VersionProps") \
|
||||
template(java_version_name, "java_version") \
|
||||
template(java_runtime_name_name, "java_runtime_name") \
|
||||
template(java_runtime_version_name, "java_runtime_version") \
|
||||
template(java_runtime_vendor_version_name, "VENDOR_VERSION") \
|
||||
|
@ -688,6 +688,7 @@ void vm_shutdown_during_initialization(const char* error, const char* message) {
|
||||
}
|
||||
|
||||
JDK_Version JDK_Version::_current;
|
||||
const char* JDK_Version::_java_version;
|
||||
const char* JDK_Version::_runtime_name;
|
||||
const char* JDK_Version::_runtime_version;
|
||||
const char* JDK_Version::_runtime_vendor_version;
|
||||
|
@ -65,6 +65,7 @@ class JDK_Version {
|
||||
private:
|
||||
|
||||
static JDK_Version _current;
|
||||
static const char* _java_version;
|
||||
static const char* _runtime_name;
|
||||
static const char* _runtime_version;
|
||||
static const char* _runtime_vendor_version;
|
||||
@ -130,6 +131,13 @@ class JDK_Version {
|
||||
|
||||
void to_string(char* buffer, size_t buflen) const;
|
||||
|
||||
static const char* java_version() {
|
||||
return _java_version;
|
||||
}
|
||||
static void set_java_version(const char* version) {
|
||||
_java_version = version;
|
||||
}
|
||||
|
||||
static const char* runtime_name() {
|
||||
return _runtime_name;
|
||||
}
|
||||
|
@ -173,15 +173,15 @@ void StatSampler::collect_sample() {
|
||||
}
|
||||
|
||||
/*
|
||||
* method to upcall into Java to return the value of the specified
|
||||
* property as a utf8 string, or NULL if does not exist. The caller
|
||||
* is responsible for setting a ResourceMark for proper cleanup of
|
||||
* the utf8 strings.
|
||||
* Call into java.lang.System.getProperty to check that the value of the
|
||||
* specified property matches
|
||||
*/
|
||||
const char* StatSampler::get_system_property(const char* name, TRAPS) {
|
||||
void StatSampler::assert_system_property(const char* name, const char* value, TRAPS) {
|
||||
#ifdef ASSERT
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
// setup the arguments to getProperty
|
||||
Handle key_str = java_lang_String::create_from_str(name, CHECK_NULL);
|
||||
Handle key_str = java_lang_String::create_from_str(name, CHECK);
|
||||
|
||||
// return value
|
||||
JavaValue result(T_OBJECT);
|
||||
@ -192,100 +192,73 @@ const char* StatSampler::get_system_property(const char* name, TRAPS) {
|
||||
vmSymbols::getProperty_name(),
|
||||
vmSymbols::string_string_signature(),
|
||||
key_str,
|
||||
CHECK_NULL);
|
||||
CHECK);
|
||||
|
||||
oop value_oop = (oop)result.get_jobject();
|
||||
if (value_oop == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
assert(value_oop != NULL, "property must have a value");
|
||||
|
||||
// convert Java String to utf8 string
|
||||
char* value = java_lang_String::as_utf8_string(value_oop);
|
||||
char* system_value = java_lang_String::as_utf8_string(value_oop);
|
||||
|
||||
return value;
|
||||
assert(strcmp(value, system_value) == 0, "property value mustn't differ from System.getProperty");
|
||||
#endif // ASSERT
|
||||
}
|
||||
|
||||
/*
|
||||
* The list of System Properties that have corresponding PerfData
|
||||
* string instrumentation created by retrieving the named property's
|
||||
* value from System.getProperty() and unconditionally creating a
|
||||
* PerfStringConstant object initialized to the retrieved value. This
|
||||
* is not an exhaustive list of Java properties with corresponding string
|
||||
* instrumentation as the create_system_property_instrumentation() method
|
||||
* creates other property based instrumentation conditionally.
|
||||
* Adds a constant counter of the given property. Asserts the value does not
|
||||
* differ from the value retrievable from System.getProperty(name)
|
||||
*/
|
||||
|
||||
// stable interface, supported counters
|
||||
static const char* property_counters_ss[] = {
|
||||
"java.vm.specification.version",
|
||||
"java.vm.specification.name",
|
||||
"java.vm.specification.vendor",
|
||||
"java.vm.version",
|
||||
"java.vm.name",
|
||||
"java.vm.vendor",
|
||||
"java.vm.info",
|
||||
"jdk.debug",
|
||||
"java.library.path",
|
||||
"java.class.path",
|
||||
"java.version",
|
||||
"java.home",
|
||||
NULL
|
||||
};
|
||||
|
||||
// unstable interface, supported counters
|
||||
static const char* property_counters_us[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
// unstable interface, unsupported counters
|
||||
static const char* property_counters_uu[] = {
|
||||
"sun.boot.library.path",
|
||||
NULL
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char** property_list;
|
||||
CounterNS name_space;
|
||||
} PropertyCounters;
|
||||
|
||||
static PropertyCounters property_counters[] = {
|
||||
{ property_counters_ss, JAVA_PROPERTY },
|
||||
{ property_counters_us, COM_PROPERTY },
|
||||
{ property_counters_uu, SUN_PROPERTY },
|
||||
{ NULL, SUN_PROPERTY }
|
||||
};
|
||||
|
||||
void StatSampler::add_property_constant(CounterNS name_space, const char* name, const char* value, TRAPS) {
|
||||
// the property must exist
|
||||
assert(value != NULL, "property name should be have a value: %s", name);
|
||||
assert_system_property(name, value, CHECK);
|
||||
if (value != NULL) {
|
||||
// create the property counter
|
||||
PerfDataManager::create_string_constant(name_space, name, value, CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to create PerfData string instruments that contain the values
|
||||
* of various system properties. String instruments are created for each
|
||||
* property specified in the property lists provided in property_counters[].
|
||||
* Adds a string constant of the given property. Retrieves the value via
|
||||
* Arguments::get_property() and asserts the value for the does not differ from
|
||||
* the value retrievable from System.getProperty()
|
||||
*/
|
||||
void StatSampler::add_property_constant(CounterNS name_space, const char* name, TRAPS) {
|
||||
add_property_constant(name_space, name, Arguments::get_property(name), CHECK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to create PerfStringConstants containing the values of various
|
||||
* system properties. Constants are created from information known to HotSpot,
|
||||
* but are initialized as-if getting the values from System.getProperty()
|
||||
* during bootstrap.
|
||||
*
|
||||
* Property counters have a counter name space prefix prepended to the
|
||||
* property name as indicated in property_counters[].
|
||||
* property name.
|
||||
*/
|
||||
void StatSampler::create_system_property_instrumentation(TRAPS) {
|
||||
|
||||
ResourceMark rm;
|
||||
// Non-writeable, constant properties
|
||||
add_property_constant(JAVA_PROPERTY, "java.vm.specification.name", "Java Virtual Machine Specification", CHECK);
|
||||
add_property_constant(JAVA_PROPERTY, "java.version", JDK_Version::java_version(), CHECK);
|
||||
add_property_constant(JAVA_PROPERTY, "java.vm.version", VM_Version::vm_release(), CHECK);
|
||||
add_property_constant(JAVA_PROPERTY, "java.vm.name", VM_Version::vm_name(), CHECK);
|
||||
add_property_constant(JAVA_PROPERTY, "java.vm.vendor", VM_Version::vm_vendor(), CHECK);
|
||||
add_property_constant(JAVA_PROPERTY, "jdk.debug", VM_Version::jdk_debug_level(), CHECK);
|
||||
|
||||
for (int i = 0; property_counters[i].property_list != NULL; i++) {
|
||||
// Get remaining property constants via Arguments::get_property,
|
||||
// which does a linear search over the internal system properties list.
|
||||
|
||||
for (int j = 0; property_counters[i].property_list[j] != NULL; j++) {
|
||||
// SUN_PROPERTY properties
|
||||
add_property_constant(SUN_PROPERTY, "sun.boot.library.path", CHECK);
|
||||
|
||||
const char* property_name = property_counters[i].property_list[j];
|
||||
assert(property_name != NULL, "property name should not be NULL");
|
||||
|
||||
const char* value = get_system_property(property_name, CHECK);
|
||||
|
||||
// the property must exist
|
||||
assert(value != NULL, "property name should be valid");
|
||||
|
||||
if (value != NULL) {
|
||||
// create the property counter
|
||||
PerfDataManager::create_string_constant(property_counters[i].name_space,
|
||||
property_name, value, CHECK);
|
||||
}
|
||||
}
|
||||
}
|
||||
// JAVA_PROPERTY properties
|
||||
add_property_constant(JAVA_PROPERTY, "java.vm.specification.version", CHECK);
|
||||
add_property_constant(JAVA_PROPERTY, "java.vm.specification.vendor", CHECK);
|
||||
add_property_constant(JAVA_PROPERTY, "java.vm.info", CHECK);
|
||||
add_property_constant(JAVA_PROPERTY, "java.library.path", CHECK);
|
||||
add_property_constant(JAVA_PROPERTY, "java.class.path", CHECK);
|
||||
add_property_constant(JAVA_PROPERTY, "java.home", CHECK);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -51,7 +51,9 @@ class StatSampler : AllStatic {
|
||||
static void create_misc_perfdata();
|
||||
static void create_sampled_perfdata();
|
||||
static void sample_data(PerfDataList* list);
|
||||
static const char* get_system_property(const char* name, TRAPS);
|
||||
static void assert_system_property(const char* name, const char* value, TRAPS);
|
||||
static void add_property_constant(CounterNS name_space, const char* name, TRAPS);
|
||||
static void add_property_constant(CounterNS name_space, const char* name, const char* value, TRAPS);
|
||||
static void create_system_property_instrumentation(TRAPS);
|
||||
|
||||
public:
|
||||
|
@ -894,11 +894,34 @@ static void create_initial_thread(Handle thread_group, JavaThread* thread,
|
||||
java_lang_Thread::RUNNABLE);
|
||||
}
|
||||
|
||||
char java_version[64] = "";
|
||||
char java_runtime_name[128] = "";
|
||||
char java_runtime_version[128] = "";
|
||||
char java_runtime_vendor_version[128] = "";
|
||||
char java_runtime_vendor_vm_bug_url[128] = "";
|
||||
|
||||
// extract the JRE version string from java.lang.VersionProps.java_version
|
||||
static const char* get_java_version(TRAPS) {
|
||||
Klass* k = SystemDictionary::find(vmSymbols::java_lang_VersionProps(),
|
||||
Handle(), Handle(), CHECK_AND_CLEAR_NULL);
|
||||
fieldDescriptor fd;
|
||||
bool found = k != NULL &&
|
||||
InstanceKlass::cast(k)->find_local_field(vmSymbols::java_version_name(),
|
||||
vmSymbols::string_signature(), &fd);
|
||||
if (found) {
|
||||
oop name_oop = k->java_mirror()->obj_field(fd.offset());
|
||||
if (name_oop == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
const char* name = java_lang_String::as_utf8_string(name_oop,
|
||||
java_version,
|
||||
sizeof(java_version));
|
||||
return name;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// extract the JRE name from java.lang.VersionProps.java_runtime_name
|
||||
static const char* get_java_runtime_name(TRAPS) {
|
||||
Klass* k = SystemDictionary::find(vmSymbols::java_lang_VersionProps(),
|
||||
@ -3383,6 +3406,7 @@ void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
|
||||
call_initPhase1(CHECK);
|
||||
|
||||
// get the Java runtime name, version, and vendor info after java.lang.System is initialized
|
||||
JDK_Version::set_java_version(get_java_version(THREAD));
|
||||
JDK_Version::set_runtime_name(get_java_runtime_name(THREAD));
|
||||
JDK_Version::set_runtime_version(get_java_runtime_version(THREAD));
|
||||
JDK_Version::set_runtime_vendor_version(get_java_runtime_vendor_version(THREAD));
|
||||
|
@ -36,6 +36,7 @@ class VersionProps {
|
||||
private static final String launcher_name =
|
||||
"@@LAUNCHER_NAME@@";
|
||||
|
||||
// This field is read by HotSpot
|
||||
private static final String java_version =
|
||||
"@@VERSION_SHORT@@";
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user