--- old/src/share/vm/ci/ciStreams.cpp 2016-06-10 17:18:54.052949893 +0200 +++ new/src/share/vm/ci/ciStreams.cpp 2016-06-10 17:18:53.824949886 +0200 @@ -278,7 +278,7 @@ // or put_static, get the referenced field. ciField* ciBytecodeStream::get_field(bool& will_link) { ciField* f = CURRENT_ENV->get_field_by_index(_holder, get_field_index()); - will_link = f->will_link(_holder, _bc); + will_link = f->will_link(_method, _bc); return f; } --- old/src/share/vm/interpreter/interpreterRuntime.cpp 2016-06-10 17:18:54.092949894 +0200 +++ new/src/share/vm/interpreter/interpreterRuntime.cpp 2016-06-10 17:18:53.888949888 +0200 @@ -558,6 +558,7 @@ // resolve field fieldDescriptor info; constantPoolHandle pool(thread, method(thread)->constants()); + methodHandle m(thread, method(thread)); bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_nofast_putfield || bytecode == Bytecodes::_putstatic); bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic); @@ -565,7 +566,7 @@ { JvmtiHideSingleStepping jhss(thread); LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode), - bytecode, CHECK); + m, bytecode, CHECK); } // end JvmtiHideSingleStepping // check if link resolution caused cpCache to be updated --- old/src/share/vm/interpreter/linkResolver.hpp 2016-06-10 17:18:54.276949899 +0200 +++ new/src/share/vm/interpreter/linkResolver.hpp 2016-06-10 17:18:53.904949888 +0200 @@ -131,19 +131,23 @@ // resolved_klass = specified class (i.e., static receiver class) // current_klass = sending method holder (i.e., class containing the method // containing the call being resolved) +// current_method = sending method (relevant for field resolution) class LinkInfo : public StackObj { Symbol* _name; // extracted from JVM_CONSTANT_NameAndType Symbol* _signature; KlassHandle _resolved_klass; // class that the constant pool entry points to KlassHandle _current_klass; // class that owns the constant pool + methodHandle _current_method; // sending method bool _check_access; constantTag _tag; + public: enum AccessCheck { - needs_access_check, - skip_access_check + needs_access_check, + skip_access_check }; + LinkInfo(const constantPoolHandle& pool, int index, methodHandle current_method, TRAPS); LinkInfo(const constantPoolHandle& pool, int index, TRAPS); // Condensed information from other call sites within the vm. @@ -151,13 +155,20 @@ AccessCheck check_access = needs_access_check, constantTag tag = JVM_CONSTANT_Invalid) : _resolved_klass(resolved_klass), - _name(name), _signature(signature), _current_klass(current_klass), + _name(name), _signature(signature), _current_klass(current_klass), _current_method(NULL), + _check_access(check_access == needs_access_check), _tag(tag) {} + + LinkInfo(KlassHandle resolved_klass, Symbol* name, Symbol* signature, methodHandle current_method, + AccessCheck check_access = needs_access_check, + constantTag tag = JVM_CONSTANT_Invalid) : + _resolved_klass(resolved_klass), + _name(name), _signature(signature), _current_klass(current_method->method_holder()), _current_method(current_method), _check_access(check_access == needs_access_check), _tag(tag) {} // Case where we just find the method and don't check access against the current class LinkInfo(KlassHandle resolved_klass, Symbol*name, Symbol* signature) : _resolved_klass(resolved_klass), - _name(name), _signature(signature), _current_klass(NULL), + _name(name), _signature(signature), _current_klass(NULL), _current_method(NULL), _check_access(false), _tag(JVM_CONSTANT_Invalid) {} // accessors @@ -165,6 +176,7 @@ Symbol* signature() const { return _signature; } KlassHandle resolved_klass() const { return _resolved_klass; } KlassHandle current_klass() const { return _current_klass; } + methodHandle current_method() const { return _current_method; } constantTag tag() const { return _tag; } bool check_access() const { return _check_access; } char* method_string() const; @@ -266,7 +278,9 @@ static void resolve_field_access(fieldDescriptor& result, const constantPoolHandle& pool, - int index, Bytecodes::Code byte, TRAPS); + int index, + const methodHandle& method, + Bytecodes::Code byte, TRAPS); static void resolve_field(fieldDescriptor& result, const LinkInfo& link_info, Bytecodes::Code access_kind, bool initialize_class, TRAPS); --- old/src/share/vm/ci/ciField.hpp 2016-06-10 17:18:54.300949900 +0200 +++ new/src/share/vm/ci/ciField.hpp 2016-06-10 17:18:54.084949894 +0200 @@ -48,7 +48,7 @@ ciType* _type; int _offset; bool _is_constant; - ciInstanceKlass* _known_to_link_with_put; + ciMethod* _known_to_link_with_put; ciInstanceKlass* _known_to_link_with_get; ciConstant _constant_value; @@ -131,8 +131,12 @@ // non-constant fields. These are java.lang.System.in // and java.lang.System.out. Abomination. // - // A field is also considered constant if it is marked @Stable - // and is non-null (or non-zero, if a primitive). + // A field is also considered constant if + // - it is marked @Stable and is non-null (or non-zero, if a primitive) or + // - it is trusted or + // - it is the target field of a CallSite object. + // + // See ciField::initialize_from() for more details. // // A user should also check the field value (constant_value().is_valid()), since // constant fields of non-initialized classes don't have values yet. @@ -150,25 +154,28 @@ ciConstant constant_value_of(ciObject* object); // Check for link time errors. Accessing a field from a - // certain class via a certain bytecode may or may not be legal. + // certain method via a certain bytecode may or may not be legal. // This call checks to see if an exception may be raised by // an access of this field. // // Usage note: if the same field is accessed multiple times // in the same compilation, will_link will need to be checked // at each point of access. - bool will_link(ciInstanceKlass* accessing_klass, + bool will_link(ciMethod* accessing_method, Bytecodes::Code bc); // Java access flags - bool is_public () const { return flags().is_public(); } - bool is_private () const { return flags().is_private(); } - bool is_protected () const { return flags().is_protected(); } - bool is_static () const { return flags().is_static(); } - bool is_final () const { return flags().is_final(); } - bool is_stable () const { return flags().is_stable(); } - bool is_volatile () const { return flags().is_volatile(); } - bool is_transient () const { return flags().is_transient(); } + bool is_public () const { return flags().is_public(); } + bool is_private () const { return flags().is_private(); } + bool is_protected () const { return flags().is_protected(); } + bool is_static () const { return flags().is_static(); } + bool is_final () const { return flags().is_final(); } + bool is_stable () const { return flags().is_stable(); } + bool is_volatile () const { return flags().is_volatile(); } + bool is_transient () const { return flags().is_transient(); } + // The field is modified outside of instance initializer methods + // (or class/initializer methods if the field is static). + bool has_initialized_final_update() const { return flags().has_initialized_final_update(); } bool is_call_site_target() { ciInstanceKlass* callsite_klass = CURRENT_ENV->CallSite_klass(); --- old/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantPool.java 2016-06-10 17:18:54.300949900 +0200 +++ new/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantPool.java 2016-06-10 17:18:54.036949892 +0200 @@ -48,16 +48,18 @@ /** * Looks up a reference to a field. If {@code opcode} is non-negative, then resolution checks - * specific to the bytecode it denotes are performed if the field is already resolved. Should + * specific to the bytecode it denotes are performed if the field is already resolved. Checks + * for some bytecodes require the method that contains the bytecode to be specified. Should * any of these checks fail, an unresolved field reference is returned. * * @param cpi the constant pool index * @param opcode the opcode of the instruction for which the lookup is being performed or * {@code -1} + * @param method the method for which the lookup is being performed * @return a reference to the field at {@code cpi} in this pool * @throws ClassFormatError if the entry at {@code cpi} is not a field */ - JavaField lookupField(int cpi, int opcode); + JavaField lookupField(int cpi, ResolvedJavaMethod method, int opcode); /** * Looks up a reference to a method. If {@code opcode} is non-negative, then resolution checks --- old/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java 2016-06-10 17:18:54.344949901 +0200 +++ new/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java 2016-06-10 17:18:54.052949893 +0200 @@ -267,8 +267,9 @@ native HotSpotResolvedObjectTypeImpl resolveTypeInPool(HotSpotConstantPool constantPool, int cpi) throws LinkageError; /** - * Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry at index {@code cpi} in - * {@code constantPool}. The values returned in {@code info} are: + * Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry for at index {@code cpi} in + * {@code constantPool}. For some opcodes, checks are performed that require the {@code method} + * that contains {@code opcode} to be specified. The values returned in {@code info} are: * *
      *     [(int) flags,   // only valid if field is resolved
@@ -281,7 +282,7 @@
      * @param info an array in which the details of the field are returned
      * @return the type defining the field if resolution is successful, 0 otherwise
      */
-    native HotSpotResolvedObjectTypeImpl resolveFieldInPool(HotSpotConstantPool constantPool, int cpi, byte opcode, long[] info);
+    native HotSpotResolvedObjectTypeImpl resolveFieldInPool(HotSpotConstantPool constantPool, int cpi, HotSpotResolvedJavaMethodImpl method, byte opcode, long[] info);
 
     /**
      * Converts {@code cpci} from an index into the cache for {@code constantPool} to an index
--- old/src/share/vm/c1/c1_Runtime1.cpp	2016-06-10 17:18:54.376949902 +0200
+++ new/src/share/vm/c1/c1_Runtime1.cpp	2016-06-10 17:18:54.164949896 +0200
@@ -759,10 +759,10 @@
   // This can be static or non-static field access
   Bytecodes::Code code       = field_access.code();
 
-  // We must load class, initialize class and resolvethe field
+  // We must load class, initialize class and resolve the field
   fieldDescriptor result; // initialize class if needed
   constantPoolHandle constants(THREAD, caller->constants());
-  LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK_NULL);
+  LinkResolver::resolve_field_access(result, constants, field_access.index(), caller, Bytecodes::java_code(code), CHECK_NULL);
   return result.field_holder();
 }
 
@@ -879,7 +879,7 @@
     fieldDescriptor result; // initialize class if needed
     Bytecodes::Code code = field_access.code();
     constantPoolHandle constants(THREAD, caller_method->constants());
-    LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK);
+    LinkResolver::resolve_field_access(result, constants, field_access.index(), caller_method, Bytecodes::java_code(code), CHECK);
     patch_field_offset = result.offset();
 
     // If we're patching a field which is volatile then at compile it
--- old/src/share/vm/c1/c1_GraphBuilder.cpp	2016-06-10 17:18:54.400949903 +0200
+++ new/src/share/vm/c1/c1_GraphBuilder.cpp	2016-06-10 17:18:54.132949895 +0200
@@ -1600,7 +1600,7 @@
   ValueType* type = as_ValueType(field_type);
   // call will_link again to determine if the field is valid.
   const bool needs_patching = !holder->is_loaded() ||
-                              !field->will_link(method()->holder(), code) ||
+                              !field->will_link(method(), code) ||
                               PatchALot;
 
   ValueStack* state_before = NULL;
--- old/src/share/vm/ci/ciField.cpp	2016-06-10 17:18:54.412949903 +0200
+++ new/src/share/vm/ci/ciField.cpp	2016-06-10 17:18:54.060949893 +0200
@@ -66,7 +66,8 @@
 
 // ------------------------------------------------------------------
 // ciField::ciField
-ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
+ciField::ciField(ciInstanceKlass* klass, int index) :
+    _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
   ASSERT_IN_VM;
   CompilerThread *thread = CompilerThread::current();
 
@@ -173,7 +174,8 @@
   initialize_from(&field_desc);
 }
 
-ciField::ciField(fieldDescriptor *fd): _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
+ciField::ciField(fieldDescriptor *fd) :
+    _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
   ASSERT_IN_VM;
 
   // Get the field's name, signature, and type.
@@ -237,7 +239,7 @@
   // Check to see if the field is constant.
   Klass* k = _holder->get_Klass();
   bool is_stable_field = FoldStableValues && is_stable();
-  if (is_final() || is_stable_field) {
+  if ((is_final() && !has_initialized_final_update()) || is_stable_field) {
     if (is_static()) {
       // This field just may be constant.  The only case where it will
       // not be constant is when the field is a *special* static & final field
@@ -265,6 +267,7 @@
     assert(SystemDictionary::CallSite_klass() != NULL, "should be already initialized");
     if (k == SystemDictionary::CallSite_klass() &&
         _offset == java_lang_invoke_CallSite::target_offset_in_bytes()) {
+      assert(!has_initialized_final_update(), "CallSite is not supposed to have writes to final fields outside initializers");
       _is_constant = true;
     } else {
       // Non-final & non-stable fields are not constants.
@@ -340,7 +343,7 @@
 //
 // Can a specific access to this field be made without causing
 // link errors?
-bool ciField::will_link(ciInstanceKlass* accessing_klass,
+bool ciField::will_link(ciMethod* accessing_method,
                         Bytecodes::Code bc) {
   VM_ENTRY_MARK;
   assert(bc == Bytecodes::_getstatic || bc == Bytecodes::_putstatic ||
@@ -363,27 +366,27 @@
   // Get and put can have different accessibility rules
   bool is_put    = (bc == Bytecodes::_putfield  || bc == Bytecodes::_putstatic);
   if (is_put) {
-    if (_known_to_link_with_put == accessing_klass) {
+    if (_known_to_link_with_put == accessing_method) {
       return true;
     }
   } else {
-    if (_known_to_link_with_get == accessing_klass) {
+    if (_known_to_link_with_get == accessing_method->holder()) {
       return true;
     }
   }
 
   LinkInfo link_info(_holder->get_instanceKlass(),
                      _name->get_symbol(), _signature->get_symbol(),
-                     accessing_klass->get_Klass());
+                     accessing_method->get_Method());
   fieldDescriptor result;
   LinkResolver::resolve_field(result, link_info, bc, false, KILL_COMPILE_ON_FATAL_(false));
 
   // update the hit-cache, unless there is a problem with memory scoping:
-  if (accessing_klass->is_shared() || !is_shared()) {
+  if (accessing_method->holder()->is_shared() || !is_shared()) {
     if (is_put) {
-      _known_to_link_with_put = accessing_klass;
+      _known_to_link_with_put = accessing_method;
     } else {
-      _known_to_link_with_get = accessing_klass;
+      _known_to_link_with_get = accessing_method->holder();
     }
   }
 
--- old/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	2016-06-10 17:18:54.448949904 +0200
+++ new/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	2016-06-10 17:18:54.084949894 +0200
@@ -587,7 +587,7 @@
     }
 
     @Override
-    public JavaField lookupField(int cpi, int opcode) {
+    public JavaField lookupField(int cpi, ResolvedJavaMethod method, int opcode) {
         final int index = rawIndexToConstantPoolIndex(cpi, opcode);
         final int nameAndTypeIndex = getNameAndTypeRefIndexAt(index);
         final int nameIndex = getNameRefIndexAt(nameAndTypeIndex);
@@ -603,7 +603,7 @@
             long[] info = new long[2];
             HotSpotResolvedObjectTypeImpl resolvedHolder;
             try {
-                resolvedHolder = compilerToVM().resolveFieldInPool(this, index, (byte) opcode, info);
+                resolvedHolder = compilerToVM().resolveFieldInPool(this, index, (HotSpotResolvedJavaMethodImpl) method, (byte) opcode, info);
             } catch (Throwable t) {
                 /*
                  * If there was an exception resolving the field we give up and return an unresolved
--- old/src/share/vm/ci/ciFlags.hpp	2016-06-10 17:18:54.476949905 +0200
+++ new/src/share/vm/ci/ciFlags.hpp	2016-06-10 17:18:54.204949897 +0200
@@ -47,20 +47,25 @@
 
 public:
   // Java access flags
-  bool is_public      () const         { return (_flags & JVM_ACC_PUBLIC      ) != 0; }
-  bool is_private     () const         { return (_flags & JVM_ACC_PRIVATE     ) != 0; }
-  bool is_protected   () const         { return (_flags & JVM_ACC_PROTECTED   ) != 0; }
-  bool is_static      () const         { return (_flags & JVM_ACC_STATIC      ) != 0; }
-  bool is_final       () const         { return (_flags & JVM_ACC_FINAL       ) != 0; }
-  bool is_synchronized() const         { return (_flags & JVM_ACC_SYNCHRONIZED) != 0; }
-  bool is_super       () const         { return (_flags & JVM_ACC_SUPER       ) != 0; }
-  bool is_volatile    () const         { return (_flags & JVM_ACC_VOLATILE    ) != 0; }
-  bool is_transient   () const         { return (_flags & JVM_ACC_TRANSIENT   ) != 0; }
-  bool is_native      () const         { return (_flags & JVM_ACC_NATIVE      ) != 0; }
-  bool is_interface   () const         { return (_flags & JVM_ACC_INTERFACE   ) != 0; }
-  bool is_abstract    () const         { return (_flags & JVM_ACC_ABSTRACT    ) != 0; }
-  bool is_strict      () const         { return (_flags & JVM_ACC_STRICT      ) != 0; }
-  bool is_stable      () const         { return (_flags & JVM_ACC_FIELD_STABLE) != 0; }
+  bool is_public               () const { return (_flags & JVM_ACC_PUBLIC                    ) != 0; }
+  bool is_private              () const { return (_flags & JVM_ACC_PRIVATE                   ) != 0; }
+  bool is_protected            () const { return (_flags & JVM_ACC_PROTECTED                 ) != 0; }
+  bool is_static               () const { return (_flags & JVM_ACC_STATIC                    ) != 0; }
+  bool is_final                () const { return (_flags & JVM_ACC_FINAL                     ) != 0; }
+  bool is_synchronized         () const { return (_flags & JVM_ACC_SYNCHRONIZED              ) != 0; }
+  bool is_super                () const { return (_flags & JVM_ACC_SUPER                     ) != 0; }
+  bool is_volatile             () const { return (_flags & JVM_ACC_VOLATILE                  ) != 0; }
+  bool is_transient            () const { return (_flags & JVM_ACC_TRANSIENT                 ) != 0; }
+  bool is_native               () const { return (_flags & JVM_ACC_NATIVE                    ) != 0; }
+  bool is_interface            () const { return (_flags & JVM_ACC_INTERFACE                 ) != 0; }
+  bool is_abstract             () const { return (_flags & JVM_ACC_ABSTRACT                  ) != 0; }
+  bool is_strict               () const { return (_flags & JVM_ACC_STRICT                    ) != 0; }
+  bool is_stable               () const { return (_flags & JVM_ACC_FIELD_STABLE              ) != 0; }
+  // In case the current object represents a field, return true if
+  // the field is modified outside of instance initializer methods
+  // (or class/initializer methods if the field is static) and false
+  // otherwise.
+  bool has_initialized_final_update() const { return (_flags & JVM_ACC_FIELD_INITIALIZED_FINAL_UPDATE) != 0; };
 
   // Conversion
   jint   as_int()                      { return _flags; }
--- old/src/share/vm/interpreter/linkResolver.cpp	2016-06-10 17:18:54.548949907 +0200
+++ new/src/share/vm/interpreter/linkResolver.cpp	2016-06-10 17:18:54.260949899 +0200
@@ -223,6 +223,22 @@
 //------------------------------------------------------------------------------------------------------------------------
 // Implementation of LinkInfo
 
+LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, methodHandle current_method, TRAPS) {
+   // resolve klass
+  Klass* result = pool->klass_ref_at(index, CHECK);
+  _resolved_klass = KlassHandle(THREAD, result);
+
+  // Get name, signature, and static klass
+  _name          = pool->name_ref_at(index);
+  _signature     = pool->signature_ref_at(index);
+  _tag           = pool->tag_ref_at(index);
+  _current_klass = KlassHandle(THREAD, pool->pool_holder());
+  _current_method = current_method;
+
+  // Coming from the constant pool always checks access
+  _check_access  = true;
+}
+
 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
    // resolve klass
   Klass* result = pool->klass_ref_at(index, CHECK);
@@ -233,6 +249,7 @@
   _signature     = pool->signature_ref_at(index);
   _tag           = pool->tag_ref_at(index);
   _current_klass = KlassHandle(THREAD, pool->pool_holder());
+  _current_method = methodHandle();
 
   // Coming from the constant pool always checks access
   _check_access  = true;
@@ -577,7 +594,7 @@
     return resolve_method(link_info, code, THREAD);
   }
 
-  LinkInfo link_info(pool, index, CHECK_NULL);
+  LinkInfo link_info(pool, index, methodHandle(), CHECK_NULL);
   resolved_klass = link_info.resolved_klass();
 
   if (pool->has_preresolution()
@@ -875,8 +892,8 @@
   }
 }
 
-void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
-  LinkInfo link_info(pool, index, CHECK);
+void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
+  LinkInfo link_info(pool, index, method, CHECK);
   resolve_field(fd, link_info, byte, true, CHECK);
 }
 
@@ -925,9 +942,40 @@
     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
   }
 
-  // Final fields can only be accessed from its own class.
-  if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) {
-    THROW(vmSymbols::java_lang_IllegalAccessError());
+  // 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());
+    }
+
+    if (CheckFinalFieldModifications &&
+        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(),
+                 current_klass()->external_name(),
+                 is_static ? "" : "");
+        THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string());
+      }
+    }
   }
 
   // initialize resolved_klass if necessary
--- old/src/share/vm/oops/method.cpp	2016-06-10 17:18:56.072949953 +0200
+++ new/src/share/vm/oops/method.cpp	2016-06-10 17:18:55.936949949 +0200
@@ -627,7 +627,7 @@
 }
 
 bool Method::is_initializer() const {
-  return name() == vmSymbols::object_initializer_name() || is_static_initializer();
+  return is_object_initializer() || is_static_initializer();
 }
 
 bool Method::has_valid_initializer_flags() const {
@@ -643,6 +643,9 @@
          has_valid_initializer_flags();
 }
 
+bool Method::is_object_initializer() const {
+   return name() == vmSymbols::object_initializer_name();
+}
 
 objArrayHandle Method::resolved_checked_exceptions_impl(Method* method, TRAPS) {
   int length = method->checked_exceptions_length();
--- old/src/share/vm/jvmci/jvmciCompilerToVM.cpp	2016-06-10 17:18:56.260949958 +0200
+++ new/src/share/vm/jvmci/jvmciCompilerToVM.cpp	2016-06-10 17:18:56.068949953 +0200
@@ -621,12 +621,12 @@
   return cp->remap_instruction_operand_from_cache(index);
 C2V_END
 
-C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode, jlongArray info_handle))
+C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jlongArray info_handle))
   ResourceMark rm;
   constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
   fieldDescriptor fd;
-  LinkInfo link_info(cp, index, CHECK_0);
+  LinkInfo link_info(cp, index, (jvmci_method != NULL) ? CompilerToVM::asMethod(jvmci_method) : NULL, CHECK_0);
   LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_0);
   typeArrayOop info = (typeArrayOop) JNIHandles::resolve(info_handle);
   assert(info != NULL && info->length() == 2, "must be");
@@ -1438,7 +1438,7 @@
   {CC "resolveConstantInPool",                        CC "(" HS_CONSTANT_POOL "I)" OBJECT,                                                  FN_PTR(resolveConstantInPool)},
   {CC "resolvePossiblyCachedConstantInPool",          CC "(" HS_CONSTANT_POOL "I)" OBJECT,                                                  FN_PTR(resolvePossiblyCachedConstantInPool)},
   {CC "resolveTypeInPool",                            CC "(" HS_CONSTANT_POOL "I)" HS_RESOLVED_KLASS,                                       FN_PTR(resolveTypeInPool)},
-  {CC "resolveFieldInPool",                           CC "(" HS_CONSTANT_POOL "IB[J)" HS_RESOLVED_KLASS,                                    FN_PTR(resolveFieldInPool)},
+  {CC "resolveFieldInPool",                           CC "(" HS_CONSTANT_POOL "I" HS_RESOLVED_METHOD "B[J)" HS_RESOLVED_KLASS,              FN_PTR(resolveFieldInPool)},
   {CC "resolveInvokeDynamicInPool",                   CC "(" HS_CONSTANT_POOL "I)V",                                                        FN_PTR(resolveInvokeDynamicInPool)},
   {CC "resolveInvokeHandleInPool",                    CC "(" HS_CONSTANT_POOL "I)V",                                                        FN_PTR(resolveInvokeHandleInPool)},
   {CC "resolveMethod",                                CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(resolveMethod)},
--- old/src/share/vm/oops/method.hpp	2016-06-10 17:18:56.212949957 +0200
+++ new/src/share/vm/oops/method.hpp	2016-06-10 17:18:55.980949950 +0200
@@ -638,6 +638,9 @@
   // valid static initializer flags.
   bool is_static_initializer() const;
 
+  // returns true if the method name is 
+  bool is_object_initializer() const;
+
   // compiled code support
   // NOTE: code() is inherently racy as deopt can be clearing code
   // simultaneously. Use with caution.
--- old/src/share/vm/opto/parse3.cpp	2016-06-10 17:18:56.300949959 +0200
+++ new/src/share/vm/opto/parse3.cpp	2016-06-10 17:18:56.116949954 +0200
@@ -109,7 +109,7 @@
     return;
   }
 
-  assert(field->will_link(method()->holder(), bc()), "getfield: typeflow responsibility");
+  assert(field->will_link(method(), bc()), "getfield: typeflow responsibility");
 
   // Note:  We do not check for an unloaded field type here any more.
 
--- old/src/share/vm/utilities/accessFlags.hpp	2016-06-10 17:18:56.388949962 +0200
+++ new/src/share/vm/utilities/accessFlags.hpp	2016-06-10 17:18:56.144949955 +0200
@@ -77,11 +77,12 @@
   // These bits must not conflict with any other field-related access flags
   // (e.g., ACC_ENUM).
   // Note that the class-related ACC_ANNOTATION bit conflicts with these flags.
-  JVM_ACC_FIELD_ACCESS_WATCHED       = 0x00002000,  // field access is watched by JVMTI
-  JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000,  // field modification is watched by JVMTI
-  JVM_ACC_FIELD_INTERNAL             = 0x00000400,  // internal field, same as JVM_ACC_ABSTRACT
-  JVM_ACC_FIELD_STABLE               = 0x00000020,  // @Stable field, same as JVM_ACC_SYNCHRONIZED
-  JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE = 0x00000800, // field has generic signature
+  JVM_ACC_FIELD_ACCESS_WATCHED            = 0x00002000, // field access is watched by JVMTI
+  JVM_ACC_FIELD_MODIFICATION_WATCHED      = 0x00008000, // field modification is watched by JVMTI
+  JVM_ACC_FIELD_INTERNAL                  = 0x00000400, // internal field, same as JVM_ACC_ABSTRACT
+  JVM_ACC_FIELD_STABLE                    = 0x00000020, // @Stable field, same as JVM_ACC_SYNCHRONIZED and JVM_ACC_SUPER
+  JVM_ACC_FIELD_INITIALIZED_FINAL_UPDATE  = 0x00000100, // (static) final field updated outside (class) initializer, same as JVM_ACC_NATIVE
+  JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE     = 0x00000800, // field has generic signature
 
   JVM_ACC_FIELD_INTERNAL_FLAGS       = JVM_ACC_FIELD_ACCESS_WATCHED |
                                        JVM_ACC_FIELD_MODIFICATION_WATCHED |
@@ -154,6 +155,8 @@
   bool is_field_access_watched() const  { return (_flags & JVM_ACC_FIELD_ACCESS_WATCHED) != 0; }
   bool is_field_modification_watched() const
                                         { return (_flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; }
+  bool has_field_initialized_final_update() const
+                                        { return (_flags & JVM_ACC_FIELD_INITIALIZED_FINAL_UPDATE) != 0; }
   bool on_stack() const                 { return (_flags & JVM_ACC_ON_STACK) != 0; }
   bool is_internal() const              { return (_flags & JVM_ACC_FIELD_INTERNAL) != 0; }
   bool is_stable() const                { return (_flags & JVM_ACC_FIELD_STABLE) != 0; }
@@ -232,6 +235,15 @@
                                            atomic_clear_bits(JVM_ACC_FIELD_MODIFICATION_WATCHED);
                                          }
                                        }
+
+  void set_has_field_initialized_final_update(const bool value) {
+    if (value) {
+      atomic_set_bits(JVM_ACC_FIELD_INITIALIZED_FINAL_UPDATE);
+    } else {
+      atomic_clear_bits(JVM_ACC_FIELD_INITIALIZED_FINAL_UPDATE);
+    }
+  }
+
   void set_field_has_generic_signature()
                                        {
                                          atomic_set_bits(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE);
--- old/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java	2016-06-10 17:18:56.448949964 +0200
+++ new/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java	2016-06-10 17:18:56.152949955 +0200
@@ -124,8 +124,8 @@
     }
 
     public static HotSpotResolvedObjectType resolveFieldInPool(
-            ConstantPool constantPool, int cpi, byte opcode, long[] info) {
-        return CTVM.resolveFieldInPool((HotSpotConstantPool) constantPool, cpi, opcode, info);
+            ConstantPool constantPool, int cpi, ResolvedJavaMethod method, byte opcode, long[] info) {
+        return CTVM.resolveFieldInPool((HotSpotConstantPool) constantPool, cpi, (HotSpotResolvedJavaMethodImpl) method, opcode, info);
     }
 
     public static int constantPoolRemapInstructionOperandFromCache(
--- old/src/share/vm/runtime/globals.hpp	2016-06-10 17:18:56.472949964 +0200
+++ new/src/share/vm/runtime/globals.hpp	2016-06-10 17:18:56.312949960 +0200
@@ -4033,6 +4033,11 @@
   experimental(bool, TrustFinalNonStaticFields, false,                      \
           "trust final non-static declarations for constant folding")       \
                                                                             \
+  diagnostic(bool, CheckFinalFieldModifications, true,                      \
+          "Check that final fields are modified only in initializers. "     \
+          "For compatibility reasons, the check has an effect only "        \
+          "for classfile version >= 51")                                    \
+                                                                            \
   diagnostic(bool, FoldStableValues, true,                                  \
           "Optimize loads from stable fields (marked w/ @Stable)")          \
                                                                             \
--- old/src/share/vm/interpreter/rewriter.cpp	2016-06-10 17:18:56.524949966 +0200
+++ new/src/share/vm/interpreter/rewriter.cpp	2016-06-10 17:18:56.256949958 +0200
@@ -406,10 +406,43 @@
           break;
         }
 
+        case Bytecodes::_putstatic      :
+        case Bytecodes::_putfield       : {
+          // Check if any final field of the class given as parameter is modified
+          // outside of initializer methods of the class. Fields that are modified
+          // are marked with a flag. For marked fields, the compilers do not perform
+          // constant folding (as the field can be changed after initialization).
+          //
+          // The check is performed after verification and only if verification has
+          // succeeded. Therefore, the class is guaranteed to be well-formed.
+          InstanceKlass* klass = method->method_holder();
+          u2 bc_index = Bytes::get_Java_u2(bcp + prefix_length + 1);
+          constantPoolHandle cp(method->constants());
+          Symbol* field_name = cp->name_ref_at(bc_index);
+          Symbol* field_sig = cp->signature_ref_at(bc_index);
+          Symbol* ref_class_name = cp->klass_name_at(cp->klass_ref_index_at(bc_index));
+
+          if (klass->name() == ref_class_name) {
+            fieldDescriptor fd;
+            klass->find_field(field_name, field_sig, &fd);
+            if (fd.access_flags().is_final()) {
+              if (fd.access_flags().is_static()) {
+                assert(c == Bytecodes::_putstatic, "must be putstatic");
+                if (!method->is_static_initializer()) {
+                  fd.set_has_initialized_final_update(true);
+                }
+              } else {
+                assert(c == Bytecodes::_putfield, "must be putfield");
+                if (!method->is_object_initializer()) {
+                  fd.set_has_initialized_final_update(true);
+                }
+              }
+            }
+          }
+        }
+        // fall through
         case Bytecodes::_getstatic      : // fall through
-        case Bytecodes::_putstatic      : // fall through
         case Bytecodes::_getfield       : // fall through
-        case Bytecodes::_putfield       : // fall through
         case Bytecodes::_invokevirtual  : // fall through
         case Bytecodes::_invokestatic   :
         case Bytecodes::_invokeinterface:
--- old/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java	2016-06-10 17:18:56.536949966 +0200
+++ new/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java	2016-06-10 17:18:56.200949956 +0200
@@ -34,6 +34,7 @@
  *          java.base/jdk.internal.org.objectweb.asm
  *          java.base/jdk.internal.org.objectweb.asm.tree
  *          jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.runtime
  *          jdk.vm.ci/jdk.vm.ci.meta
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build sun.hotspot.WhiteBox
--- old/test/compiler/jvmci/compilerToVM/ConstantPoolTestCase.java	2016-06-10 17:18:56.524949966 +0200
+++ new/test/compiler/jvmci/compilerToVM/ConstantPoolTestCase.java	2016-06-10 17:18:56.256949958 +0200
@@ -27,6 +27,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
 import sun.hotspot.WhiteBox;
 import jdk.internal.reflect.ConstantPool;
 import jdk.internal.reflect.ConstantPool.Tag;
@@ -184,13 +185,24 @@
         public final String klass;
         public final String name;
         public final String type;
+        public final ResolvedJavaMethod[] methods;
         public final byte[] opcodes;
         public final long accFlags;
 
         public TestedCPEntry(String klass, String name, String type, byte[] opcodes, long accFlags) {
+                this(klass, name, type, null, opcodes, accFlags);
+        }
+
+        public TestedCPEntry(String klass, String name, String type, ResolvedJavaMethod[] methods, byte[] opcodes, long accFlags) {
             this.klass = klass;
             this.name = name;
             this.type = type;
+            if (methods != null) {
+                this.methods = new ResolvedJavaMethod[methods.length];
+                System.arraycopy(methods, 0, this.methods, 0, methods.length);
+            } else {
+                this.methods = null;
+            }
             if (opcodes != null) {
                 this.opcodes = new byte[opcodes.length];
                 System.arraycopy(opcodes, 0, this.opcodes, 0, opcodes.length);
--- old/src/share/vm/runtime/fieldDescriptor.hpp	2016-06-10 17:18:56.492949965 +0200
+++ new/src/share/vm/runtime/fieldDescriptor.hpp	2016-06-10 17:18:56.192949956 +0200
@@ -106,6 +106,7 @@
   bool is_field_access_watched()  const    { return access_flags().is_field_access_watched(); }
   bool is_field_modification_watched() const
                                            { return access_flags().is_field_modification_watched(); }
+  bool has_initialized_final_update() const { return access_flags().has_field_initialized_final_update(); }
   bool has_generic_signature()    const    { return access_flags().field_has_generic_signature(); }
 
   void set_is_field_access_watched(const bool value) {
@@ -118,6 +119,11 @@
     update_klass_field_access_flag();
   }
 
+  void set_has_initialized_final_update(const bool value) {
+    _access_flags.set_has_field_initialized_final_update(value);
+    update_klass_field_access_flag();
+  }
+
   // Initialization
   void reinitialize(InstanceKlass* ik, int index);
 
--- old/test/compiler/jvmci/compilerToVM/ConstantPoolTestsHelper.java	2016-06-10 17:18:56.560949967 +0200
+++ new/test/compiler/jvmci/compilerToVM/ConstantPoolTestsHelper.java	2016-06-10 17:18:56.324949960 +0200
@@ -31,6 +31,10 @@
 import compiler.jvmci.compilerToVM.ConstantPoolTestCase.TestedCPEntry;
 import java.util.HashMap;
 import java.util.Map;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.runtime.JVMCI;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import sun.hotspot.WhiteBox;
@@ -44,6 +48,7 @@
 public class ConstantPoolTestsHelper {
 
     public static final int NO_CP_CACHE_PRESENT = Integer.MAX_VALUE;
+    private static final MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
 
     public enum DummyClasses {
         DUMMY_CLASS(MultipleImplementer2.class, CP_MAP_FOR_CLASS),
@@ -76,6 +81,45 @@
         }
     }
 
+    /**
+     * Obtain a resolved Java method declared by a given type.
+     *
+     * @param type the declaring type
+     * @param the method's name
+     *
+     * Currently, the lookup is based only on the method's name
+     * but not on the method's signature (i.e., the first method
+     * with a matching name declared on {@code type} is returned).
+     */
+    private static ResolvedJavaMethod getMethod(ResolvedJavaType type, String methodName) {
+        if (methodName.equals("")) {
+            return type.getClassInitializer();
+        }
+
+        if (methodName.equals("")) {
+            ResolvedJavaMethod[] initializers = type.getDeclaredConstructors();
+            if (initializers.length >= 0) {
+                return initializers[0];
+            } else {
+                throw new IllegalArgumentException();
+            }
+        }
+
+        for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
+            if (method.getName().equals(methodName)) {
+                return method;
+            }
+        }
+
+        throw new IllegalArgumentException();
+    }
+
+    private static ResolvedJavaType getType(Class clazz) {
+        ResolvedJavaType type = metaAccess.lookupJavaType(clazz);
+        type.initialize();
+        return type;
+    }
+
     private static final Map CP_MAP_FOR_CLASS = new HashMap<>();
     static {
         CP_MAP_FOR_CLASS.put(CONSTANT_CLASS,
@@ -141,6 +185,7 @@
                     new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
                                       "objectField",
                                       "Ljava/lang/Object;",
+                                      new ResolvedJavaMethod[] { getMethod(getType(MultipleImplementer2.class), ""), null },
                                       new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
                                       Opcodes.ACC_FINAL),
                     new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2",
@@ -296,6 +341,7 @@
                     new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
                                       "objectField",
                                       "Ljava/lang/Object;",
+                                      new ResolvedJavaMethod[] { getMethod(getType(MultipleAbstractImplementer.class), ""), null },
                                       new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD},
                                       Opcodes.ACC_FINAL),
                     new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer",
@@ -401,6 +447,7 @@
                     new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface",
                                       "OBJECT_CONSTANT",
                                       "Ljava/lang/Object;",
+                                      new ResolvedJavaMethod[] { getMethod(getType(MultipleImplementersInterface.class), ""), null },
                                       new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC},
                                       Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC),
                 }
--- old/test/compiler/jvmci/compilerToVM/LookupKlassRefIndexInPoolTest.java	2016-06-10 17:18:56.792949974 +0200
+++ new/test/compiler/jvmci/compilerToVM/LookupKlassRefIndexInPoolTest.java	2016-06-10 17:18:56.728949972 +0200
@@ -33,6 +33,7 @@
  *          java.base/jdk.internal.org.objectweb.asm
  *          java.base/jdk.internal.org.objectweb.asm.tree
  *          jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.runtime
  *          jdk.vm.ci/jdk.vm.ci.meta
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build sun.hotspot.WhiteBox
--- old/test/compiler/jvmci/compilerToVM/LookupNameAndTypeRefIndexInPoolTest.java	2016-06-10 17:18:58.300950019 +0200
+++ new/test/compiler/jvmci/compilerToVM/LookupNameAndTypeRefIndexInPoolTest.java	2016-06-10 17:18:58.148950014 +0200
@@ -33,6 +33,7 @@
  *          java.base/jdk.internal.org.objectweb.asm
  *          java.base/jdk.internal.org.objectweb.asm.tree
  *          jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.runtime
  *          jdk.vm.ci/jdk.vm.ci.meta
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build sun.hotspot.WhiteBox
--- old/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java	2016-06-10 17:18:58.348950020 +0200
+++ new/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java	2016-06-10 17:18:58.144950014 +0200
@@ -33,6 +33,7 @@
  *          java.base/jdk.internal.reflect
  *          java.base/jdk.internal.org.objectweb.asm
  *          jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.runtime
  *          jdk.vm.ci/jdk.vm.ci.meta
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build sun.hotspot.WhiteBox
--- old/test/compiler/jvmci/compilerToVM/LookupSignatureInPoolTest.java	2016-06-10 17:18:58.364950021 +0200
+++ new/test/compiler/jvmci/compilerToVM/LookupSignatureInPoolTest.java	2016-06-10 17:18:58.096950013 +0200
@@ -33,6 +33,7 @@
  *          java.base/jdk.internal.org.objectweb.asm
  *          java.base/jdk.internal.org.objectweb.asm.tree
  *          jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.runtime
  *          jdk.vm.ci/jdk.vm.ci.meta
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build sun.hotspot.WhiteBox
--- old/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java	2016-06-10 17:18:58.392950021 +0200
+++ new/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java	2016-06-10 17:18:58.172950015 +0200
@@ -32,6 +32,7 @@
  *          java.base/jdk.internal.reflect
  *          java.base/jdk.internal.org.objectweb.asm
  *          jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.runtime
  *          jdk.vm.ci/jdk.vm.ci.meta
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build sun.hotspot.WhiteBox
--- old/test/compiler/jvmci/compilerToVM/LookupNameInPoolTest.java	2016-06-10 17:18:58.396950022 +0200
+++ new/test/compiler/jvmci/compilerToVM/LookupNameInPoolTest.java	2016-06-10 17:18:58.160950015 +0200
@@ -33,6 +33,7 @@
  *          java.base/jdk.internal.org.objectweb.asm
  *          java.base/jdk.internal.org.objectweb.asm.tree
  *          jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.runtime
  *          jdk.vm.ci/jdk.vm.ci.meta
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build sun.hotspot.WhiteBox
--- old/test/compiler/jvmci/compilerToVM/LookupMethodInPoolTest.java	2016-06-10 17:18:58.448950023 +0200
+++ new/test/compiler/jvmci/compilerToVM/LookupMethodInPoolTest.java	2016-06-10 17:18:58.176950015 +0200
@@ -34,6 +34,7 @@
  *          java.base/jdk.internal.org.objectweb.asm.tree
  *          jdk.vm.ci/jdk.vm.ci.hotspot
  *          jdk.vm.ci/jdk.vm.ci.meta
+ *          jdk.vm.ci/jdk.vm.ci.runtime
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build sun.hotspot.WhiteBox
  *        compiler.jvmci.compilerToVM.LookupMethodInPoolTest
--- old/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java	2016-06-10 17:18:58.468950024 +0200
+++ new/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java	2016-06-10 17:18:58.220950016 +0200
@@ -34,6 +34,7 @@
  *          java.base/jdk.internal.org.objectweb.asm.tree
  *          jdk.vm.ci/jdk.vm.ci.hotspot
  *          jdk.vm.ci/jdk.vm.ci.meta
+ *          jdk.vm.ci/jdk.vm.ci.runtime
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build sun.hotspot.WhiteBox
  *        compiler.jvmci.compilerToVM.ResolveFieldInPoolTest
@@ -107,6 +108,7 @@
             HotSpotResolvedObjectType fieldToVerify
                     = CompilerToVMHelper.resolveFieldInPool(constantPoolCTVM,
                                                            index,
+                                                           entry.methods == null ? null : entry.methods[j],
                                                            entry.opcodes[j],
                                                            info);
             String msg = String.format("Object returned by resolveFieldInPool method"
--- old/test/compiler/jvmci/compilerToVM/ResolvePossiblyCachedConstantInPoolTest.java	2016-06-10 17:18:58.480950024 +0200
+++ new/test/compiler/jvmci/compilerToVM/ResolvePossiblyCachedConstantInPoolTest.java	2016-06-10 17:18:58.308950019 +0200
@@ -33,6 +33,7 @@
  *          java.base/jdk.internal.org.objectweb.asm
  *          java.base/jdk.internal.org.objectweb.asm.tree
  *          jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.runtime
  *          jdk.vm.ci/jdk.vm.ci.meta
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build sun.hotspot.WhiteBox