diff -r f1b6c4079be0 -r 279174cb3a24 src/hotspot/share/interpreter/linkResolver.cpp --- a/src/hotspot/share/interpreter/linkResolver.cpp Mon Apr 23 16:15:26 2018 -0700 +++ b/src/hotspot/share/interpreter/linkResolver.cpp Mon May 14 09:05:20 2018 -0400 @@ -974,68 +974,68 @@ THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); } - if (!link_info.check_access()) - // Access checking may be turned off when calling from within the VM. - return; + // Access checking may be turned off when calling from within the VM. + Klass* current_klass = link_info.current_klass(); + if (link_info.check_access()) { - // check access - Klass* current_klass = link_info.current_klass(); - check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK); + // check access + check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK); - // check for errors - if (is_static != fd.is_static()) { - ResourceMark rm(THREAD); - char msg[200]; - jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string()); - THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg); - } - - // A final field can be modified only - // (1) by methods declared in the class declaring the field and - // (2) by the method (in case of a static field) - // or by the method (in case of an instance field). - if (is_put && fd.access_flags().is_final()) { - ResourceMark rm(THREAD); - stringStream ss; - - if (sel_klass != current_klass) { - ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class", - is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(), - current_klass->external_name()); - THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string()); + // check for errors + if (is_static != fd.is_static()) { + ResourceMark rm(THREAD); + char msg[200]; + jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string()); + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg); } - if (fd.constants()->pool_holder()->major_version() >= 53) { - methodHandle m = link_info.current_method(); - assert(!m.is_null(), "information about the current method must be available for 'put' bytecodes"); - bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic && - fd.is_static() && - !m()->is_static_initializer()); - bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) && - !fd.is_static() && - !m->is_object_initializer()); + // A final field can be modified only + // (1) by methods declared in the class declaring the field and + // (2) by the method (in case of a static field) + // or by the method (in case of an instance field). + if (is_put && fd.access_flags().is_final()) { + ResourceMark rm(THREAD); + stringStream ss; - if (is_initialized_static_final_update || is_initialized_instance_final_update) { - ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ", + if (sel_klass != current_klass) { + ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class", is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(), - m()->name()->as_C_string(), - is_static ? "" : ""); + current_klass->external_name()); THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string()); } + + if (fd.constants()->pool_holder()->major_version() >= 53) { + methodHandle m = link_info.current_method(); + assert(!m.is_null(), "information about the current method must be available for 'put' bytecodes"); + bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic && + fd.is_static() && + !m()->is_static_initializer()); + bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) && + !fd.is_static() && + !m->is_object_initializer()); + + if (is_initialized_static_final_update || is_initialized_instance_final_update) { + ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ", + is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(), + m()->name()->as_C_string(), + is_static ? "" : ""); + THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string()); + } + } + } + + // initialize resolved_klass if necessary + // note 1: the klass which declared the field must be initialized (i.e, sel_klass) + // according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99) + // + // note 2: we don't want to force initialization if we are just checking + // if the field access is legal; e.g., during compilation + if (is_static && initialize_class) { + sel_klass->initialize(CHECK); } } - // initialize resolved_klass if necessary - // note 1: the klass which declared the field must be initialized (i.e, sel_klass) - // according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99) - // - // note 2: we don't want to force initialization if we are just checking - // if the field access is legal; e.g., during compilation - if (is_static && initialize_class) { - sel_klass->initialize(CHECK); - } - - if (sel_klass != current_klass) { + if ((sel_klass != current_klass) && (current_klass != NULL)) { check_field_loader_constraints(field, sig, current_klass, sel_klass, CHECK); }