--- old/src/share/vm/interpreter/interpreterRuntime.cpp 2016-06-29 16:52:32.770960182 +0200 +++ new/src/share/vm/interpreter/interpreterRuntime.cpp 2016-06-29 16:52:32.598960177 +0200 @@ -592,9 +592,24 @@ !klass->is_initialized()); Bytecodes::Code get_code = (Bytecodes::Code)0; + /* Do not cache the result of the resolution for putfield instructions + * to instance final fields. + * + * A putfield instruction targeting an instance final field must throw + * an IllegalAccessError if the instruction is not in an instance + * initializer method . Without the check below, a putfield + * in an initializer method is resolved; subsequent putfield instructions + * to the same field then use cached information and thus do not pass + * through the VM (i.e., checks will not be executed for those instructions). + */ + bool final_instance_update = info.field_holder()->major_version() >= 53 && + info.has_initialized_final_update() && + (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_nofast_putfield); + + if (!uninitialized_static) { get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield); - if (is_put || !info.access_flags().is_final()) { + if ((is_put && !final_instance_update) || !info.access_flags().is_final()) { put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield); } }