< prev index next >
src/hotspot/share/oops/instanceKlass.cpp
Print this page
*** 29,38 ****
--- 29,39 ----
#include "classfile/classFileStream.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/moduleEntry.hpp"
+ #include "classfile/resolutionErrors.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/systemDictionaryShared.hpp"
#include "classfile/verifier.hpp"
#include "classfile/vmSymbols.hpp"
*** 132,141 ****
--- 133,143 ----
#define DTRACE_CLASSINIT_PROBE(type, thread_type)
#define DTRACE_CLASSINIT_PROBE_WAIT(type, thread_type, wait)
#endif // ndef DTRACE_ENABLED
+
static inline bool is_class_loader(const Symbol* class_name,
const ClassFileParser& parser) {
assert(class_name != NULL, "invariant");
if (class_name == vmSymbols::java_lang_ClassLoader()) {
*** 224,237 ****
// 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;
}
--- 226,238 ----
// 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, the nest host resolution/validation error,
! // are idempotent.
InstanceKlass* InstanceKlass::nest_host(TRAPS) {
InstanceKlass* nest_host_k = _nest_host;
if (nest_host_k != NULL) {
return nest_host_k;
}
*** 259,274 ****
stringStream ss;
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;
! log_trace(class, nestmates)("%s", _nest_host_res_error);
} else {
// A valid nest-host is an instance class in the current package that lists this
// class as a nest member. If any of these conditions are not met the class is
// its own nest-host.
const char* error = NULL;
--- 260,275 ----
stringStream ss;
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);
! const char* msg = ss.as_string(true /* on C-heap */);
! constantPoolHandle cph(THREAD, constants());
! SystemDictionary::add_nest_host_error(cph, _nest_host_index, msg);
CLEAR_PENDING_EXCEPTION;
! log_trace(class, nestmates)("%s", msg);
} else {
// A valid nest-host is an instance class in the current package that lists this
// class as a nest member. If any of these conditions are not met the class is
// its own nest-host.
const char* error = NULL;
*** 314,338 ****
this->external_name(),
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();
!
! log_trace(class, nestmates)("%s", _nest_host_res_error);
}
}
} else {
log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self",
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
--- 315,338 ----
this->external_name(),
this->class_loader_data()->loader_name_and_id(),
k->external_name(),
k->class_loader_data()->loader_name_and_id(),
error);
! const char* msg = ss.as_string(true /* on C-heap */);
! constantPoolHandle cph(THREAD, constants());
! SystemDictionary::add_nest_host_error(cph, _nest_host_index, msg);
! log_trace(class, nestmates)("%s", msg);
}
}
} else {
log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self",
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_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
*** 345,356 ****
// assert some of those facts.
void InstanceKlass::set_nest_host(InstanceKlass* host, TRAPS) {
assert(is_hidden(), "must be a hidden class");
assert(host != NULL, "NULL nest host specified");
assert(_nest_host == NULL, "current class has resolved nest-host");
! assert(_nest_host_res_error == NULL, "unexpected nest host resolution error exists: %s",
! _nest_host_res_error);
assert((host->_nest_host == NULL && host->_nest_host_index == 0) ||
(host->_nest_host == host), "proposed host is not a valid nest-host");
// Can't assert this as package is not set yet:
// assert(is_same_class_package(host), "proposed host is in wrong package");
--- 345,356 ----
// assert some of those facts.
void InstanceKlass::set_nest_host(InstanceKlass* host, TRAPS) {
assert(is_hidden(), "must be a hidden class");
assert(host != NULL, "NULL nest host specified");
assert(_nest_host == NULL, "current class has resolved nest-host");
! assert(nest_host_error(THREAD) == NULL, "unexpected nest host resolution error exists: %s",
! nest_host_error(THREAD));
assert((host->_nest_host == NULL && host->_nest_host_index == 0) ||
(host->_nest_host == host), "proposed host is not a valid nest-host");
// Can't assert this as package is not set yet:
// assert(is_same_class_package(host), "proposed host is in wrong package");
*** 404,413 ****
--- 404,422 ----
access ? "" : "NOT ",
k->external_name());
return access;
}
+ const char* InstanceKlass::nest_host_error(TRAPS) {
+ if (_nest_host_index == 0) {
+ return NULL;
+ } else {
+ constantPoolHandle cph(THREAD, constants());
+ return SystemDictionary::find_nest_host_error(cph, (int)_nest_host_index);
+ }
+ }
+
InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) {
bool is_hidden_or_anonymous = parser.is_hidden() || parser.is_unsafe_anonymous();
const int size = InstanceKlass::size(parser.vtable_size(),
parser.itable_size(),
nonstatic_oop_map_size(parser.total_oop_map_count()),
*** 474,484 ****
InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind, KlassID id) :
Klass(id),
_nest_members(NULL),
_nest_host_index(0),
_nest_host(NULL),
- _nest_host_res_error(NULL),
_record_components(NULL),
_static_field_size(parser.static_field_size()),
_nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())),
_itable_len(parser.itable_size()),
_init_thread(NULL),
--- 483,492 ----
*** 2460,2470 ****
_methods_jmethod_ids = NULL;
_jni_ids = NULL;
_oop_map_cache = NULL;
// clear _nest_host to ensure re-load at runtime
_nest_host = NULL;
- _nest_host_res_error = NULL;
_package_entry = NULL;
_dep_context_last_cleaned = 0;
}
void InstanceKlass::remove_java_mirror() {
--- 2468,2477 ----
*** 2626,2641 ****
// unreference array name derived from this class name (arrays of an unloaded
// class can't be referenced anymore).
if (_array_name != NULL) _array_name->decrement_refcount();
FREE_C_HEAP_ARRAY(char, _source_debug_extension);
-
- // deallocate memoized nest-host resolution error
- if (_nest_host_res_error != NULL) {
- FREE_C_HEAP_ARRAY(char, _nest_host_res_error);
- _nest_host_res_error = NULL;
- }
}
void InstanceKlass::set_source_debug_extension(const char* array, int length) {
if (array == NULL) {
_source_debug_extension = NULL;
--- 2633,2642 ----
< prev index next >