< prev index next >
src/hotspot/share/oops/instanceKlass.cpp
Print this page
rev 59277 : [mq]: v3
@@ -224,22 +224,23 @@
// set once this method returns.
// Any errors from nest-host resolution must be preserved so they can be queried
// from higher-level access checking code, and reported as part of access checking
// exceptions.
// VirtualMachineErrors are propagated with a NULL return.
+// Under any conditions where the _nest_host can be set to non-NULL the resulting value
+// of it and, if applicable, _nest_host_res_error, are idempotent. But as we can be
+// executing this code concurrently we need to ensure ordering is maintained so that
+// errors messages can safely be read.
InstanceKlass* InstanceKlass::nest_host(TRAPS) {
InstanceKlass* nest_host_k = _nest_host;
if (nest_host_k != NULL) {
return nest_host_k;
}
const bool doLog = log_is_enabled(Trace, class, nestmates);
- // need to resolve and save our nest-host class. This could be attempted
- // concurrently but as the result is idempotent and we don't use the class
- // then we do not need any synchronization beyond what is implicitly used
- // during class loading.
+ // need to resolve and save our nest-host class.
if (_nest_host_index != 0) { // we have a real nest_host
// Before trying to resolve check if we're in a suitable context
if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) {
if (doLog) {
ResourceMark rm(THREAD);
@@ -266,10 +267,12 @@
char* target_host_class = _constants->klass_name_at(_nest_host_index)->as_C_string();
ss.print("Nest host resolution of %s with host %s failed: ",
this->external_name(), target_host_class);
java_lang_Throwable::print(PENDING_EXCEPTION, &ss);
_nest_host_res_error = ss.as_string(true /* on C-heap */);
+ // ensure we see _nest_host_res_error is set if _nest_host is non-NULL
+ OrderAccess::storestore();
CLEAR_PENDING_EXCEPTION;
if (doLog) {
log_trace(class, nestmates)("%s", _nest_host_res_error);
}
} else {
@@ -323,10 +326,12 @@
this->class_loader_data()->loader_name_and_id(),
k->external_name(),
k->class_loader_data()->loader_name_and_id(),
error);
_nest_host_res_error = ss.as_string(true /* on C-heap */);
+ // ensure we see _nest_host_res_error is set if _nest_host is non-NULL
+ OrderAccess::storestore();
if (doLog) {
log_trace(class, nestmates)("%s", _nest_host_res_error);
}
}
@@ -338,11 +343,12 @@
this->external_name());
}
}
// Either not in an explicit nest, or else an error occurred, so
- // the nest-host is set to `this`.
+ // the nest-host is set to `this`. Any thread that sees this assignment
+ // will also see any setting of _nest_host_res_error, if applicable.
return (_nest_host = this);
}
// Dynamic nest member support: set this class's nest host to the given class.
// This occurs as part of the class definition, as soon as the instanceKlass
< prev index next >