--- old/src/hotspot/share/oops/instanceKlass.cpp 2020-03-11 01:12:49.481351211 -0400 +++ new/src/hotspot/share/oops/instanceKlass.cpp 2020-03-11 01:12:48.336338482 -0400 @@ -226,6 +226,10 @@ // 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) { @@ -234,10 +238,7 @@ 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()) { @@ -268,6 +269,8 @@ 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); @@ -325,6 +328,8 @@ 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); @@ -340,7 +345,8 @@ } // 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); }