src/share/vm/interpreter/interpreterRuntime.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
8163880 Cdiff src/share/vm/interpreter/interpreterRuntime.cpp
src/share/vm/interpreter/interpreterRuntime.cpp
Print this page
*** 574,600 ****
if (cp_cache_entry->is_resolved(bytecode)) return;
// compute auxiliary field attributes
TosState state = as_TosState(info.field_type());
! // Put instructions on final fields are not resolved. This is required so we throw
! // exceptions at the correct place (when the instruction is actually invoked).
// If we do not resolve an instruction in the current pass, leaving the put_code
// set to zero will cause the next put instruction to the same field to reresolve.
//
// Also, we need to delay resolving getstatic and putstatic instructions until the
// class is initialized. This is required so that access to the static
// field will call the initialization function every time until the class
// is completely initialized ala. in 2.17.5 in JVM Specification.
InstanceKlass* klass = InstanceKlass::cast(info.field_holder());
bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) &&
!klass->is_initialized());
Bytecodes::Code put_code = (Bytecodes::Code)0;
! if (is_put && !info.access_flags().is_final() && !uninitialized_static) {
put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
}
Bytecodes::Code get_code = (Bytecodes::Code)0;
if (!uninitialized_static) {
get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield);
}
--- 574,620 ----
if (cp_cache_entry->is_resolved(bytecode)) return;
// compute auxiliary field attributes
TosState state = as_TosState(info.field_type());
! // Resolution of put instructions on final fields is delayed. That is required so that
! // exceptions are thrown at the correct place (when the instruction is actually invoked).
// If we do not resolve an instruction in the current pass, leaving the put_code
// set to zero will cause the next put instruction to the same field to reresolve.
+
+ // Resolution of put instructions to final instance fields with invalid updates (i.e.,
+ // to final instance fields with updates originating from a method different than <init>)
+ // is inhibited. A putfield instruction targeting an instance final field must throw
+ // an IllegalAccessError if the instruction is not in an instance
+ // initializer method <init>. If resolution were not inhibited, a putfield
+ // in an initializer method could be resolved in the initializer. Subsequent
+ // putfield instructions to the same field would then use cached information.
+ // As a result, those instructions would not pass through the VM. That is,
+ // checks in resolve_field_access() would not be executed for those instructions
+ // and the required IllegalAccessError would not not be thrown.
//
// Also, we need to delay resolving getstatic and putstatic instructions until the
// class is initialized. This is required so that access to the static
// field will call the initialization function every time until the class
// is completely initialized ala. in 2.17.5 in JVM Specification.
InstanceKlass* klass = InstanceKlass::cast(info.field_holder());
bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) &&
!klass->is_initialized());
Bytecodes::Code put_code = (Bytecodes::Code)0;
! bool has_initialized_final_update = info.field_holder()->major_version() >= 53 &&
! info.has_initialized_final_update();
!
! if (has_initialized_final_update) {
! assert(info.access_flags().is_final(), "Fields with initialized final updates must be final");
! }
!
! if (!uninitialized_static) {
! if ((is_put && !has_initialized_final_update) || !info.access_flags().is_final()) {
put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
}
+ }
Bytecodes::Code get_code = (Bytecodes::Code)0;
if (!uninitialized_static) {
get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield);
}
src/share/vm/interpreter/interpreterRuntime.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File