< prev index next >
src/hotspot/share/interpreter/interpreterRuntime.cpp
Print this page
*** 378,393 ****
return (type2size[field_type] + type2size[T_OBJECT]) * AbstractInterpreter::stackElementSize;
JRT_END
JRT_ENTRY(void, InterpreterRuntime::uninitialized_static_value_field(JavaThread* thread, oopDesc* mirror, int index))
// The interpreter tries to access a flattenable static field that has not been initialized.
! // This situation can happen only if the load or initialization of the field failed during step 8 of
! // the initialization of the holder of the field. The code below tries to load and initialize
! // the field's class again in order to throw likely the same exception or error as the one that caused
! // the field initialization to fail.
instanceHandle mirror_h(THREAD, (instanceOop)mirror);
InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
int offset = klass->field_offset(index);
Klass* field_k = klass->get_value_field_klass_or_null(index);
if (field_k == NULL) {
field_k = SystemDictionary::resolve_or_fail(klass->field_signature(index)->fundamental_name(THREAD),
Handle(THREAD, klass->class_loader()),
--- 378,400 ----
return (type2size[field_type] + type2size[T_OBJECT]) * AbstractInterpreter::stackElementSize;
JRT_END
JRT_ENTRY(void, InterpreterRuntime::uninitialized_static_value_field(JavaThread* thread, oopDesc* mirror, int index))
// The interpreter tries to access a flattenable static field that has not been initialized.
! // This situation can happen in different scenarios:
! // 1 - if the load or initialization of the field failed during step 8 of
! // the initialization of the holder of the field, in this case the access to the field
! // must fail
! // 2 - it can also happen when the initialization of the holder class triggered the initialization of
! // another class which accesses this field in its static initializer, in this case the
! // access must succeed to allow circularity
! // The code below tries to load and initialize the field's class again before returning the default value.
! // If the field was not initialized because of an error, a exception should be thrown.
! // If the class is being initialized, the default value is returned.
instanceHandle mirror_h(THREAD, (instanceOop)mirror);
InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
+ if (klass->is_being_initialized() && klass->is_reentrant_initialization(THREAD)) {
int offset = klass->field_offset(index);
Klass* field_k = klass->get_value_field_klass_or_null(index);
if (field_k == NULL) {
field_k = SystemDictionary::resolve_or_fail(klass->field_signature(index)->fundamental_name(THREAD),
Handle(THREAD, klass->class_loader()),
*** 395,405 ****
true, CHECK);
assert(field_k != NULL, "Should have been loaded or an exception thrown above");
klass->set_value_field_klass(index, field_k);
}
field_k->initialize(CHECK);
! fatal("An exception should have been thrown above");
JRT_END
JRT_ENTRY(void, InterpreterRuntime::uninitialized_instance_value_field(JavaThread* thread, oopDesc* obj, int index))
instanceHandle obj_h(THREAD, (instanceOop)obj);
InstanceKlass* klass = InstanceKlass::cast(obj_h()->klass());
--- 402,432 ----
true, CHECK);
assert(field_k != NULL, "Should have been loaded or an exception thrown above");
klass->set_value_field_klass(index, field_k);
}
field_k->initialize(CHECK);
! oop defaultvalue = ValueKlass::cast(field_k)->default_value();
! // It is safe to initialized the static field because 1) the current thread is the initializing thread
! // and is the only one that can access it, and 2) the field is actually not initialized (i.e. null)
! // otherwise the JVM should not be executing this code.
! mirror->obj_field_put(offset, defaultvalue);
! thread->set_vm_result(defaultvalue);
! } else {
! assert(klass->is_in_error_state(), "If not initializing, initialization must have failed to get there");
! ResourceMark rm(THREAD);
! const char* desc = "Could not initialize class ";
! const char* className = klass->external_name();
! size_t msglen = strlen(desc) + strlen(className) + 1;
! char* message = NEW_RESOURCE_ARRAY(char, msglen);
! if (NULL == message) {
! // Out of memory: can't create detailed error message
! THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), className);
! } else {
! jio_snprintf(message, msglen, "%s%s", desc, className);
! THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), message);
! }
! }
JRT_END
JRT_ENTRY(void, InterpreterRuntime::uninitialized_instance_value_field(JavaThread* thread, oopDesc* obj, int index))
instanceHandle obj_h(THREAD, (instanceOop)obj);
InstanceKlass* klass = InstanceKlass::cast(obj_h()->klass());
< prev index next >