src/share/vm/interpreter/linkResolver.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/interpreter/linkResolver.cpp	Thu Jun  2 10:38:19 2016
--- new/src/share/vm/interpreter/linkResolver.cpp	Thu Jun  2 10:38:18 2016

*** 221,239 **** --- 221,240 ---- #endif //------------------------------------------------------------------------------------------------------------------------ // 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); _current_klass = KlassHandle(THREAD, pool->pool_holder()); + _current_method = current_method; // Coming from the constant pool always checks access _check_access = true; }
*** 570,584 **** --- 571,585 ---- if (code == Bytecodes::_invokedynamic) { resolved_klass = SystemDictionary::MethodHandle_klass(); Symbol* method_name = vmSymbols::invoke_name(); Symbol* method_signature = pool->signature_ref_at(index); KlassHandle current_klass(THREAD, pool->pool_holder()); ! LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass, NULL); return resolve_method(link_info, /*require_methodref*/false, THREAD); } ! LinkInfo link_info(pool, index, NULL, CHECK_NULL); resolved_klass = link_info.resolved_klass(); if (pool->has_preresolution() || (resolved_klass() == SystemDictionary::MethodHandle_klass() && MethodHandles::is_signature_polymorphic_name(resolved_klass(), link_info.name()))) {
*** 855,866 **** --- 856,867 ---- ); return; } } ! 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); } void LinkResolver::resolve_field(fieldDescriptor& fd, const LinkInfo& link_info,
*** 905,918 **** --- 906,930 ---- 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); } // Final fields can only be accessed from its own class. if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) { + // A final field can be modified only + // (1) by methods declared in the class declaring the field and + // (2) by the <clinit> method (in case of a static field) + // or by the <init> method (in case of an instance field). + if (is_put && fd.access_flags().is_final()) { + methodHandle m = link_info.current_method(); + assert(!m.is_null(), "information about the current method must be available for 'put' bytecodes"); + Symbol* method_name = m->name(); + if (sel_klass() != current_klass() || + (byte == Bytecodes::_putstatic && fd.is_static() && method_name != vmSymbols::class_initializer_name()) || + ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) && !fd.is_static() && method_name != vmSymbols::object_initializer_name()) + ) { THROW(vmSymbols::java_lang_IllegalAccessError()); } + } // 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) //
*** 954,964 **** --- 966,976 ---- // Initialize klass (this should only happen if everything is ok) if (initialize_class && resolved_klass->should_be_initialized()) { resolved_klass->initialize(CHECK); // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?) LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(), ! link_info.current_klass(), NULL, link_info.check_access()); resolved_method = linktime_resolve_static_method(new_info, CHECK); } assert(save_resolved_method == resolved_method(), "does this change?"); // setup result
*** 1480,1490 **** --- 1492,1502 ---- const methodHandle& attached_method, Bytecodes::Code byte, TRAPS) { KlassHandle defc = attached_method->method_holder(); Symbol* name = attached_method->name(); Symbol* type = attached_method->signature(); ! LinkInfo link_info(defc, name, type, KlassHandle(), NULL, /*check_access=*/false); switch(byte) { case Bytecodes::_invokevirtual: resolve_virtual_call(result, recv, recv->klass(), link_info, /*check_null_and_abstract=*/true, CHECK); break;
*** 1502,1542 **** --- 1514,1554 ---- fatal("bad call: %s", Bytecodes::name(byte)); } } void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) { ! LinkInfo link_info(pool, index, NULL, CHECK); resolve_static_call(result, link_info, /*initialize_class*/true, CHECK); } void LinkResolver::resolve_invokespecial(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) { ! LinkInfo link_info(pool, index, NULL, CHECK); resolve_special_call(result, link_info, CHECK); } void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, TRAPS) { ! LinkInfo link_info(pool, index, NULL, CHECK); KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass()); resolve_virtual_call(result, recv, recvrKlass, link_info, /*check_null_or_abstract*/true, CHECK); } void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, TRAPS) { ! LinkInfo link_info(pool, index, NULL, CHECK); KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass()); resolve_interface_call(result, recv, recvrKlass, link_info, true, CHECK); } void LinkResolver::resolve_invokehandle(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) { // This guy is reached from InterpreterRuntime::resolve_invokehandle. ! LinkInfo link_info(pool, index, NULL, CHECK); if (TraceMethodHandles) { ResourceMark rm(THREAD); tty->print_cr("resolve_invokehandle %s %s", link_info.name()->as_C_string(), link_info.signature()->as_C_string()); }

src/share/vm/interpreter/linkResolver.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File