Skip to content

Commit f7c59c6

Browse files
committed
8255231: Avoid upcalls when initializing the statSampler
Reviewed-by: iklam, dholmes
1 parent dccfd2b commit f7c59c6

File tree

7 files changed

+95
-85
lines changed

7 files changed

+95
-85
lines changed

src/hotspot/share/classfile/vmSymbols.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
\
148148
/* Java runtime version access */ \
149149
template(java_lang_VersionProps, "java/lang/VersionProps") \
150+
template(java_version_name, "java_version") \
150151
template(java_runtime_name_name, "java_runtime_name") \
151152
template(java_runtime_version_name, "java_runtime_version") \
152153
template(java_runtime_vendor_version_name, "VENDOR_VERSION") \

src/hotspot/share/runtime/java.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,7 @@ void vm_shutdown_during_initialization(const char* error, const char* message) {
688688
}
689689

690690
JDK_Version JDK_Version::_current;
691+
const char* JDK_Version::_java_version;
691692
const char* JDK_Version::_runtime_name;
692693
const char* JDK_Version::_runtime_version;
693694
const char* JDK_Version::_runtime_vendor_version;

src/hotspot/share/runtime/java.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class JDK_Version {
6565
private:
6666

6767
static JDK_Version _current;
68+
static const char* _java_version;
6869
static const char* _runtime_name;
6970
static const char* _runtime_version;
7071
static const char* _runtime_vendor_version;
@@ -130,6 +131,13 @@ class JDK_Version {
130131

131132
void to_string(char* buffer, size_t buflen) const;
132133

134+
static const char* java_version() {
135+
return _java_version;
136+
}
137+
static void set_java_version(const char* version) {
138+
_java_version = version;
139+
}
140+
133141
static const char* runtime_name() {
134142
return _runtime_name;
135143
}

src/hotspot/share/runtime/statSampler.cpp

Lines changed: 57 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -173,15 +173,15 @@ void StatSampler::collect_sample() {
173173
}
174174

175175
/*
176-
* method to upcall into Java to return the value of the specified
177-
* property as a utf8 string, or NULL if does not exist. The caller
178-
* is responsible for setting a ResourceMark for proper cleanup of
179-
* the utf8 strings.
176+
* Call into java.lang.System.getProperty to check that the value of the
177+
* specified property matches
180178
*/
181-
const char* StatSampler::get_system_property(const char* name, TRAPS) {
179+
void StatSampler::assert_system_property(const char* name, const char* value, TRAPS) {
180+
#ifdef ASSERT
181+
ResourceMark rm(THREAD);
182182

183183
// setup the arguments to getProperty
184-
Handle key_str = java_lang_String::create_from_str(name, CHECK_NULL);
184+
Handle key_str = java_lang_String::create_from_str(name, CHECK);
185185

186186
// return value
187187
JavaValue result(T_OBJECT);
@@ -192,100 +192,73 @@ const char* StatSampler::get_system_property(const char* name, TRAPS) {
192192
vmSymbols::getProperty_name(),
193193
vmSymbols::string_string_signature(),
194194
key_str,
195-
CHECK_NULL);
195+
CHECK);
196196

197197
oop value_oop = (oop)result.get_jobject();
198-
if (value_oop == NULL) {
199-
return NULL;
200-
}
198+
assert(value_oop != NULL, "property must have a value");
201199

202200
// convert Java String to utf8 string
203-
char* value = java_lang_String::as_utf8_string(value_oop);
201+
char* system_value = java_lang_String::as_utf8_string(value_oop);
204202

205-
return value;
203+
assert(strcmp(value, system_value) == 0, "property value mustn't differ from System.getProperty");
204+
#endif // ASSERT
206205
}
207206

208207
/*
209-
* The list of System Properties that have corresponding PerfData
210-
* string instrumentation created by retrieving the named property's
211-
* value from System.getProperty() and unconditionally creating a
212-
* PerfStringConstant object initialized to the retrieved value. This
213-
* is not an exhaustive list of Java properties with corresponding string
214-
* instrumentation as the create_system_property_instrumentation() method
215-
* creates other property based instrumentation conditionally.
208+
* Adds a constant counter of the given property. Asserts the value does not
209+
* differ from the value retrievable from System.getProperty(name)
216210
*/
211+
void StatSampler::add_property_constant(CounterNS name_space, const char* name, const char* value, TRAPS) {
212+
// the property must exist
213+
assert(value != NULL, "property name should be have a value: %s", name);
214+
assert_system_property(name, value, CHECK);
215+
if (value != NULL) {
216+
// create the property counter
217+
PerfDataManager::create_string_constant(name_space, name, value, CHECK);
218+
}
219+
}
217220

218-
// stable interface, supported counters
219-
static const char* property_counters_ss[] = {
220-
"java.vm.specification.version",
221-
"java.vm.specification.name",
222-
"java.vm.specification.vendor",
223-
"java.vm.version",
224-
"java.vm.name",
225-
"java.vm.vendor",
226-
"java.vm.info",
227-
"jdk.debug",
228-
"java.library.path",
229-
"java.class.path",
230-
"java.version",
231-
"java.home",
232-
NULL
233-
};
234-
235-
// unstable interface, supported counters
236-
static const char* property_counters_us[] = {
237-
NULL
238-
};
239-
240-
// unstable interface, unsupported counters
241-
static const char* property_counters_uu[] = {
242-
"sun.boot.library.path",
243-
NULL
244-
};
245-
246-
typedef struct {
247-
const char** property_list;
248-
CounterNS name_space;
249-
} PropertyCounters;
250-
251-
static PropertyCounters property_counters[] = {
252-
{ property_counters_ss, JAVA_PROPERTY },
253-
{ property_counters_us, COM_PROPERTY },
254-
{ property_counters_uu, SUN_PROPERTY },
255-
{ NULL, SUN_PROPERTY }
256-
};
257-
221+
/*
222+
* Adds a string constant of the given property. Retrieves the value via
223+
* Arguments::get_property() and asserts the value for the does not differ from
224+
* the value retrievable from System.getProperty()
225+
*/
226+
void StatSampler::add_property_constant(CounterNS name_space, const char* name, TRAPS) {
227+
add_property_constant(name_space, name, Arguments::get_property(name), CHECK);
228+
}
258229

259230
/*
260-
* Method to create PerfData string instruments that contain the values
261-
* of various system properties. String instruments are created for each
262-
* property specified in the property lists provided in property_counters[].
231+
* Method to create PerfStringConstants containing the values of various
232+
* system properties. Constants are created from information known to HotSpot,
233+
* but are initialized as-if getting the values from System.getProperty()
234+
* during bootstrap.
235+
*
263236
* Property counters have a counter name space prefix prepended to the
264-
* property name as indicated in property_counters[].
237+
* property name.
265238
*/
266239
void StatSampler::create_system_property_instrumentation(TRAPS) {
267240

268-
ResourceMark rm;
269-
270-
for (int i = 0; property_counters[i].property_list != NULL; i++) {
271-
272-
for (int j = 0; property_counters[i].property_list[j] != NULL; j++) {
273-
274-
const char* property_name = property_counters[i].property_list[j];
275-
assert(property_name != NULL, "property name should not be NULL");
276-
277-
const char* value = get_system_property(property_name, CHECK);
278-
279-
// the property must exist
280-
assert(value != NULL, "property name should be valid");
281-
282-
if (value != NULL) {
283-
// create the property counter
284-
PerfDataManager::create_string_constant(property_counters[i].name_space,
285-
property_name, value, CHECK);
286-
}
287-
}
288-
}
241+
// Non-writeable, constant properties
242+
add_property_constant(JAVA_PROPERTY, "java.vm.specification.name", "Java Virtual Machine Specification", CHECK);
243+
add_property_constant(JAVA_PROPERTY, "java.version", JDK_Version::java_version(), CHECK);
244+
add_property_constant(JAVA_PROPERTY, "java.vm.version", VM_Version::vm_release(), CHECK);
245+
add_property_constant(JAVA_PROPERTY, "java.vm.name", VM_Version::vm_name(), CHECK);
246+
add_property_constant(JAVA_PROPERTY, "java.vm.vendor", VM_Version::vm_vendor(), CHECK);
247+
add_property_constant(JAVA_PROPERTY, "jdk.debug", VM_Version::jdk_debug_level(), CHECK);
248+
249+
// Get remaining property constants via Arguments::get_property,
250+
// which does a linear search over the internal system properties list.
251+
252+
// SUN_PROPERTY properties
253+
add_property_constant(SUN_PROPERTY, "sun.boot.library.path", CHECK);
254+
255+
// JAVA_PROPERTY properties
256+
add_property_constant(JAVA_PROPERTY, "java.vm.specification.version", CHECK);
257+
add_property_constant(JAVA_PROPERTY, "java.vm.specification.vendor", CHECK);
258+
add_property_constant(JAVA_PROPERTY, "java.vm.info", CHECK);
259+
add_property_constant(JAVA_PROPERTY, "java.library.path", CHECK);
260+
add_property_constant(JAVA_PROPERTY, "java.class.path", CHECK);
261+
add_property_constant(JAVA_PROPERTY, "java.home", CHECK);
289262
}
290263

291264
/*

src/hotspot/share/runtime/statSampler.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ class StatSampler : AllStatic {
5151
static void create_misc_perfdata();
5252
static void create_sampled_perfdata();
5353
static void sample_data(PerfDataList* list);
54-
static const char* get_system_property(const char* name, TRAPS);
54+
static void assert_system_property(const char* name, const char* value, TRAPS);
55+
static void add_property_constant(CounterNS name_space, const char* name, TRAPS);
56+
static void add_property_constant(CounterNS name_space, const char* name, const char* value, TRAPS);
5557
static void create_system_property_instrumentation(TRAPS);
5658

5759
public:

src/hotspot/share/runtime/thread.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,11 +894,34 @@ static void create_initial_thread(Handle thread_group, JavaThread* thread,
894894
java_lang_Thread::RUNNABLE);
895895
}
896896

897+
char java_version[64] = "";
897898
char java_runtime_name[128] = "";
898899
char java_runtime_version[128] = "";
899900
char java_runtime_vendor_version[128] = "";
900901
char java_runtime_vendor_vm_bug_url[128] = "";
901902

903+
// extract the JRE version string from java.lang.VersionProps.java_version
904+
static const char* get_java_version(TRAPS) {
905+
Klass* k = SystemDictionary::find(vmSymbols::java_lang_VersionProps(),
906+
Handle(), Handle(), CHECK_AND_CLEAR_NULL);
907+
fieldDescriptor fd;
908+
bool found = k != NULL &&
909+
InstanceKlass::cast(k)->find_local_field(vmSymbols::java_version_name(),
910+
vmSymbols::string_signature(), &fd);
911+
if (found) {
912+
oop name_oop = k->java_mirror()->obj_field(fd.offset());
913+
if (name_oop == NULL) {
914+
return NULL;
915+
}
916+
const char* name = java_lang_String::as_utf8_string(name_oop,
917+
java_version,
918+
sizeof(java_version));
919+
return name;
920+
} else {
921+
return NULL;
922+
}
923+
}
924+
902925
// extract the JRE name from java.lang.VersionProps.java_runtime_name
903926
static const char* get_java_runtime_name(TRAPS) {
904927
Klass* k = SystemDictionary::find(vmSymbols::java_lang_VersionProps(),
@@ -3383,6 +3406,7 @@ void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
33833406
call_initPhase1(CHECK);
33843407

33853408
// get the Java runtime name, version, and vendor info after java.lang.System is initialized
3409+
JDK_Version::set_java_version(get_java_version(THREAD));
33863410
JDK_Version::set_runtime_name(get_java_runtime_name(THREAD));
33873411
JDK_Version::set_runtime_version(get_java_runtime_version(THREAD));
33883412
JDK_Version::set_runtime_vendor_version(get_java_runtime_vendor_version(THREAD));

src/java.base/share/classes/java/lang/VersionProps.java.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class VersionProps {
3636
private static final String launcher_name =
3737
"@@LAUNCHER_NAME@@";
3838

39+
// This field is read by HotSpot
3940
private static final String java_version =
4041
"@@VERSION_SHORT@@";
4142

0 commit comments

Comments
 (0)