< prev index next >

src/hotspot/share/oops/instanceKlass.cpp

Print this page
rev 59277 : [mq]: v3

*** 224,245 **** // 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. 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. 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); --- 224,246 ---- // 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. 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,275 **** --- 267,278 ---- 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,332 **** --- 326,337 ---- 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,348 **** this->external_name()); } } // Either not in an explicit nest, or else an error occurred, so ! // the nest-host is set to `this`. 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 --- 343,354 ---- this->external_name()); } } // Either not in an explicit nest, or else an error occurred, so ! // 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 >