# HG changeset patch # User hseigel # Date 1447968075 0 # Node ID 62db4b48cbef26d8377b0596b8e3907bfc8efa51 # Parent 5a67344e5ef3ce27ef80a528bce132c1039e7d63# Parent 4cc9d7af1b01d31a87c30bbd33d670f4d58ca533 Merge diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/ci/ciEnv.cpp --- a/hotspot/src/share/vm/ci/ciEnv.cpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/ci/ciEnv.cpp Thu Nov 19 21:21:15 2015 +0000 @@ -704,14 +704,13 @@ InstanceKlass* holder, Symbol* name, Symbol* sig, - Bytecodes::Code bc, - constantTag tag) { + Bytecodes::Code bc) { EXCEPTION_CONTEXT; KlassHandle h_accessor(THREAD, accessor); KlassHandle h_holder(THREAD, holder); LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL)); methodHandle dest_method; - LinkInfo link_info(h_holder, name, sig, h_accessor, LinkInfo::needs_access_check, tag); + LinkInfo link_info(h_holder, name, sig, h_accessor, /*check_access*/true); switch (bc) { case Bytecodes::_invokestatic: dest_method = @@ -797,9 +796,7 @@ if (holder_is_accessible) { // Our declared holder is loaded. InstanceKlass* lookup = declared_holder->get_instanceKlass(); - constantTag tag = cpool->tag_ref_at(index); - assert(accessor->get_instanceKlass() == cpool->pool_holder(), "not the pool holder?"); - Method* m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc, tag); + Method* m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); if (m != NULL && (bc == Bytecodes::_invokestatic ? m->method_holder()->is_not_initialized() diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/ci/ciEnv.hpp --- a/hotspot/src/share/vm/ci/ciEnv.hpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/ci/ciEnv.hpp Thu Nov 19 21:21:15 2015 +0000 @@ -158,8 +158,7 @@ InstanceKlass* holder, Symbol* name, Symbol* sig, - Bytecodes::Code bc, - constantTag tag); + Bytecodes::Code bc); // Get a ciObject from the object factory. Ensures uniqueness // of ciObjects. diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/ci/ciMethod.cpp --- a/hotspot/src/share/vm/ci/ciMethod.cpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/ci/ciMethod.cpp Thu Nov 19 21:21:15 2015 +0000 @@ -786,8 +786,7 @@ Symbol* h_name = name()->get_symbol(); Symbol* h_signature = signature()->get_symbol(); - LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass, - check_access ? LinkInfo::needs_access_check : LinkInfo::skip_access_check); + LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass, check_access); methodHandle m; // Only do exact lookup if receiver klass has been linked. Otherwise, // the vtable has not been setup, and the LinkResolver will fail. diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/classfile/symbolTable.cpp --- a/hotspot/src/share/vm/classfile/symbolTable.cpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp Thu Nov 19 21:21:15 2015 +0000 @@ -97,7 +97,7 @@ int SymbolTable::_symbols_counted = 0; volatile int SymbolTable::_parallel_claimed_idx = 0; -void SymbolTable::buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total) { +void SymbolTable::buckets_unlink(int start_idx, int end_idx, int* processed, int* removed) { for (int i = start_idx; i < end_idx; ++i) { HashtableEntry** p = the_table()->bucket_addr(i); HashtableEntry* entry = the_table()->bucket(i); @@ -110,7 +110,6 @@ break; } Symbol* s = entry->literal(); - (*memory_total) += s->size(); (*processed)++; assert(s != NULL, "just checking"); // If reference count is zero, remove. @@ -133,15 +132,9 @@ // This is done late during GC. void SymbolTable::unlink(int* processed, int* removed) { size_t memory_total = 0; - buckets_unlink(0, the_table()->table_size(), processed, removed, &memory_total); + buckets_unlink(0, the_table()->table_size(), processed, removed); _symbols_removed += *removed; _symbols_counted += *processed; - // Exclude printing for normal PrintGCDetails because people parse - // this output. - if (PrintGCDetails && Verbose && WizardMode) { - gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", *processed, - (memory_total*HeapWordSize)/1024); - } } void SymbolTable::possibly_parallel_unlink(int* processed, int* removed) { @@ -158,16 +151,10 @@ } int end_idx = MIN2(limit, start_idx + ClaimChunkSize); - buckets_unlink(start_idx, end_idx, processed, removed, &memory_total); + buckets_unlink(start_idx, end_idx, processed, removed); } Atomic::add(*processed, &_symbols_counted); Atomic::add(*removed, &_symbols_removed); - // Exclude printing for normal PrintGCDetails because people parse - // this output. - if (PrintGCDetails && Verbose && WizardMode) { - gclog_or_tty->print(" [Symbols: scanned=%d removed=%d size=" SIZE_FORMAT "K] ", *processed, *removed, - (memory_total*HeapWordSize)/1024); - } } // Create a new table and using alternate hash code, populate the new table diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/classfile/symbolTable.hpp --- a/hotspot/src/share/vm/classfile/symbolTable.hpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/classfile/symbolTable.hpp Thu Nov 19 21:21:15 2015 +0000 @@ -132,7 +132,7 @@ static volatile int _parallel_claimed_idx; // Release any dead symbols - static void buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total); + static void buckets_unlink(int start_idx, int end_idx, int* processed, int* removed); public: enum { symbol_alloc_batch_size = 8, diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/interpreter/linkResolver.cpp --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Nov 19 21:21:15 2015 +0000 @@ -245,7 +245,6 @@ // 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()); // Coming from the constant pool always checks access @@ -682,15 +681,6 @@ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); } - // check tag at call is method - if (!link_info.tag().is_invalid() && !link_info.tag().is_method()) { - ResourceMark rm(THREAD); - char buf[200]; - jio_snprintf(buf, sizeof(buf), "Resolving to non regular method %s", link_info.method_string()); - THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); - } - - // 2. lookup method in resolved klass and its super klasses methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL); @@ -750,14 +740,6 @@ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); } - // check tag at call is an interface method - if (!link_info.tag().is_invalid() && !link_info.tag().is_interface_method()) { - ResourceMark rm(THREAD); - char buf[200]; - jio_snprintf(buf, sizeof(buf), "Resolving to non interface method %s", link_info.method_string()); - THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); - } - // lookup method in this interface or its super, java.lang.Object // JDK8: also look for static methods methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL); @@ -935,8 +917,7 @@ 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(), - link_info.check_access() ? LinkInfo::needs_access_check : LinkInfo::skip_access_check); + link_info.current_klass(), link_info.check_access()); resolved_method = linktime_resolve_static_method(new_info, CHECK); } diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/interpreter/linkResolver.hpp --- a/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Nov 19 21:21:15 2015 +0000 @@ -135,35 +135,20 @@ KlassHandle _resolved_klass; // class that the constant pool entry points to KlassHandle _current_klass; // class that owns the constant pool bool _check_access; - constantTag _tag; public: - enum AccessCheck { - needs_access_check, - skip_access_check - }; - LinkInfo(const constantPoolHandle& pool, int index, TRAPS); - // Condensed information from other call sites within the vm. - LinkInfo(KlassHandle resolved_klass, Symbol* name, Symbol* signature, KlassHandle current_klass, - AccessCheck check_access = needs_access_check, - constantTag tag = JVM_CONSTANT_Invalid) : + LinkInfo(KlassHandle resolved_klass, Symbol* name, Symbol* signature, + KlassHandle current_klass, bool check_access = true) : _resolved_klass(resolved_klass), _name(name), _signature(signature), _current_klass(current_klass), - _check_access(check_access == needs_access_check && current_klass.not_null()), _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), - _check_access(false), _tag(JVM_CONSTANT_Invalid) {} + _check_access(check_access) {} // accessors Symbol* name() const { return _name; } Symbol* signature() const { return _signature; } KlassHandle resolved_klass() const { return _resolved_klass; } KlassHandle current_klass() const { return _current_klass; } - constantTag tag() const { return _tag; } bool check_access() const { return _check_access; } char* method_string() const; diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp --- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Nov 19 21:21:15 2015 +0000 @@ -574,7 +574,7 @@ if (holder_klass->is_interface()) { // do link-time resolution to check all access rules. - LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass); + LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass, true); methodHandle resolved_method = LinkResolver::linktime_resolve_interface_method_or_null(link_info); if (resolved_method.is_null() || resolved_method->is_private()) { return NULL; @@ -586,7 +586,7 @@ return JNIHandles::make_local(THREAD, result); } else { // do link-time resolution to check all access rules. - LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass); + LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass, true); methodHandle resolved_method = LinkResolver::linktime_resolve_virtual_method_or_null(link_info); if (resolved_method.is_null()) { return NULL; diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/jvmci/jvmciEnv.cpp --- a/hotspot/src/share/vm/jvmci/jvmciEnv.cpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/jvmci/jvmciEnv.cpp Thu Nov 19 21:21:15 2015 +0000 @@ -282,12 +282,11 @@ instanceKlassHandle& h_holder, Symbol* name, Symbol* sig, - Bytecodes::Code bc, - constantTag tag) { + Bytecodes::Code bc) { JVMCI_EXCEPTION_CONTEXT; LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL)); methodHandle dest_method; - LinkInfo link_info(h_holder, name, sig, h_accessor, LinkInfo::needs_access_check, tag); + LinkInfo link_info(h_holder, name, sig, h_accessor, /*check_access*/true); switch (bc) { case Bytecodes::_invokestatic: dest_method = @@ -360,8 +359,7 @@ if (holder_is_accessible) { // Our declared holder is loaded. instanceKlassHandle lookup = get_instance_klass_for_declared_method_holder(holder); - constantTag tag = cpool->tag_ref_at(index); - methodHandle m = lookup_method(accessor, lookup, name_sym, sig_sym, bc, tag); + methodHandle m = lookup_method(accessor, lookup, name_sym, sig_sym, bc); if (!m.is_null() && (bc == Bytecodes::_invokestatic ? InstanceKlass::cast(m->method_holder())->is_not_initialized() diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/jvmci/jvmciEnv.hpp --- a/hotspot/src/share/vm/jvmci/jvmciEnv.hpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/jvmci/jvmciEnv.hpp Thu Nov 19 21:21:15 2015 +0000 @@ -125,8 +125,7 @@ instanceKlassHandle& holder, Symbol* name, Symbol* sig, - Bytecodes::Code bc, - constantTag tag); + Bytecodes::Code bc); private: diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/oops/constantPool.cpp --- a/hotspot/src/share/vm/oops/constantPool.cpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/oops/constantPool.cpp Thu Nov 19 21:21:15 2015 +0000 @@ -409,19 +409,6 @@ return extract_high_short_from_int(ref_index); } -constantTag ConstantPool::impl_tag_ref_at(int which, bool uncached) { - int pool_index = which; - if (!uncached && cache() != NULL) { - if (ConstantPool::is_invokedynamic_index(which)) { - // Invokedynamic index is index into resolved_references - pool_index = invokedynamic_cp_cache_entry_at(which)->constant_pool_index(); - } else { - // change byte-ordering and go via cache - pool_index = remap_instruction_operand_from_cache(which); - } - } - return tag_at(pool_index); -} int ConstantPool::impl_klass_ref_index_at(int which, bool uncached) { guarantee(!ConstantPool::is_invokedynamic_index(which), @@ -677,7 +664,6 @@ int callee_index = this_cp->method_handle_klass_index_at(index); Symbol* name = this_cp->method_handle_name_ref_at(index); Symbol* signature = this_cp->method_handle_signature_ref_at(index); - constantTag m_tag = this_cp->tag_at(this_cp->method_handle_index_at(index)); if (PrintMiscellaneous) tty->print_cr("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s", ref_kind, index, this_cp->method_handle_index_at(index), @@ -686,15 +672,6 @@ { Klass* k = klass_at_impl(this_cp, callee_index, true, CHECK_NULL); callee = KlassHandle(THREAD, k); } - if ((callee->is_interface() && m_tag.is_method()) || - (!callee->is_interface() && m_tag.is_interface_method())) { - ResourceMark rm(THREAD); - char buf[200]; - jio_snprintf(buf, sizeof(buf), "Inconsistent constant data for %s.%s%s at index %d", - callee->name()->as_C_string(), name->as_C_string(), signature->as_C_string(), index); - THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); - } - KlassHandle klass(THREAD, this_cp->pool_holder()); Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind, callee, name, signature, diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/oops/constantPool.hpp --- a/hotspot/src/share/vm/oops/constantPool.hpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/oops/constantPool.hpp Thu Nov 19 21:21:15 2015 +0000 @@ -664,8 +664,6 @@ int remap_instruction_operand_from_cache(int operand); // operand must be biased by CPCACHE_INDEX_TAG - constantTag tag_ref_at(int cp_cache_index) { return impl_tag_ref_at(cp_cache_index, false); } - // Lookup for entries consisting of (name_index, signature_index) int name_ref_index_at(int which_nt); // == low-order jshort of name_and_type_at(which_nt) int signature_ref_index_at(int which_nt); // == high-order jshort of name_and_type_at(which_nt) @@ -786,7 +784,6 @@ Symbol* impl_signature_ref_at(int which, bool uncached); int impl_klass_ref_index_at(int which, bool uncached); int impl_name_and_type_ref_index_at(int which, bool uncached); - constantTag impl_tag_ref_at(int which, bool uncached); // Used while constructing constant pool (only by ClassFileParser) jint klass_index_at(int which) { diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/prims/methodHandles.cpp --- a/hotspot/src/share/vm/prims/methodHandles.cpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/prims/methodHandles.cpp Thu Nov 19 21:21:15 2015 +0000 @@ -679,7 +679,7 @@ case IS_METHOD: { CallInfo result; - LinkInfo link_info(defc, name, type, caller); + LinkInfo link_info(defc, name, type, caller, caller.not_null()); { assert(!HAS_PENDING_EXCEPTION, ""); if (ref_kind == JVM_REF_invokeStatic) { @@ -716,7 +716,7 @@ case IS_CONSTRUCTOR: { CallInfo result; - LinkInfo link_info(defc, name, type, caller); + LinkInfo link_info(defc, name, type, caller, caller.not_null()); { assert(!HAS_PENDING_EXCEPTION, ""); if (name == vmSymbols::object_initializer_name()) { @@ -737,7 +737,7 @@ fieldDescriptor result; // find_field initializes fd if found { assert(!HAS_PENDING_EXCEPTION, ""); - LinkInfo link_info(defc, name, type, caller, LinkInfo::skip_access_check); + LinkInfo link_info(defc, name, type, caller, /*check_access*/false); LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD); if (HAS_PENDING_EXCEPTION) { return empty; diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/runtime/javaCalls.cpp --- a/hotspot/src/share/vm/runtime/javaCalls.cpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/runtime/javaCalls.cpp Thu Nov 19 21:21:15 2015 +0000 @@ -183,7 +183,7 @@ CallInfo callinfo; Handle receiver = args->receiver(); KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass()); - LinkInfo link_info(spec_klass, name, signature); + LinkInfo link_info(spec_klass, name, signature, KlassHandle(), /*check_access*/false); LinkResolver::resolve_virtual_call( callinfo, receiver, recvrKlass, link_info, true, CHECK); methodHandle method = callinfo.selected_method(); @@ -220,7 +220,7 @@ void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; - LinkInfo link_info(klass, name, signature); + LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false); LinkResolver::resolve_special_call(callinfo, link_info, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); @@ -255,7 +255,7 @@ void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; - LinkInfo link_info(klass, name, signature); + LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false); LinkResolver::resolve_static_call(callinfo, link_info, true, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/src/share/vm/runtime/reflection.cpp --- a/hotspot/src/share/vm/runtime/reflection.cpp Thu Nov 19 11:54:32 2015 -0500 +++ b/hotspot/src/share/vm/runtime/reflection.cpp Thu Nov 19 21:21:15 2015 +0000 @@ -830,7 +830,7 @@ Symbol* signature = method->signature(); Symbol* name = method->name(); LinkResolver::resolve_interface_call(info, receiver, recv_klass, - LinkInfo(klass, name, signature), + LinkInfo(klass, name, signature, KlassHandle(), false), true, CHECK_(methodHandle())); return info.selected_method(); diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/test/runtime/8087223/BadMethodHandles.java --- a/hotspot/test/runtime/8087223/BadMethodHandles.java Thu Nov 19 11:54:32 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,250 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * $bug 8087223 - * @summary Adding constantTag to keep method call consistent with it. - * @compile -XDignore.symbol.file BadMethodHandles.java - * @run main/othervm BadMethodHandles - */ - -import jdk.internal.org.objectweb.asm.*; -import java.io.FileOutputStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import static jdk.internal.org.objectweb.asm.Opcodes.*; - -public class BadMethodHandles { - - static byte[] dumpBadInterfaceMethodref() { - ClassWriter cw = new ClassWriter(0); - cw.visit(52, ACC_PUBLIC | ACC_SUPER, "BadInterfaceMethodref", null, "java/lang/Object", null); - Handle handle1 = - new Handle(Opcodes.H_INVOKEINTERFACE, "BadInterfaceMethodref", "m", "()V"); - Handle handle2 = - new Handle(Opcodes.H_INVOKEINTERFACE, "BadInterfaceMethodref", "staticM", "()V"); - - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "m", "()V", null, null); - mv.visitCode(); - mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); - mv.visitLdcInsn("hello from m"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false/*intf*/); - mv.visitInsn(RETURN); - mv.visitMaxs(3, 1); - mv.visitEnd(); - } - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "staticM", "()V", null, null); - mv.visitCode(); - mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); - mv.visitLdcInsn("hello from staticM"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false/*intf*/); - mv.visitInsn(RETURN); - mv.visitMaxs(3, 1); - mv.visitEnd(); - } - - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "runm", "()V", null, null); - mv.visitCode(); - // REF_invokeStatic - mv.visitLdcInsn(handle1); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invoke", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "runStaticM", "()V", null, null); - mv.visitCode(); - // REF_invokeStatic - mv.visitLdcInsn(handle2); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invoke", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - - cw.visitEnd(); - return cw.toByteArray(); - } - - static byte[] dumpIBad() { - ClassWriter cw = new ClassWriter(0); - cw.visit(52, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, "IBad", null, "java/lang/Object", null); - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "m", "()V", null, null); - mv.visitCode(); - mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); - mv.visitLdcInsn("hello from m"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false/*intf*/); - mv.visitInsn(RETURN); - mv.visitMaxs(3, 1); - mv.visitEnd(); - } - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "staticM", "()V", null, null); - mv.visitCode(); - mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); - mv.visitLdcInsn("hello from staticM"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false/*intf*/); - mv.visitInsn(RETURN); - mv.visitMaxs(3, 1); - mv.visitEnd(); - } - cw.visitEnd(); - return cw.toByteArray(); - } - - static byte[] dumpBadMethodref() { - ClassWriter cw = new ClassWriter(0); - cw.visit(52, ACC_PUBLIC | ACC_SUPER, "BadMethodref", null, "java/lang/Object", new String[]{"IBad"}); - Handle handle1 = - new Handle(Opcodes.H_INVOKEINTERFACE, "BadMethodref", "m", "()V"); - Handle handle2 = - new Handle(Opcodes.H_INVOKEINTERFACE, "BadMethodref", "staticM", "()V"); - - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "runm", "()V", null, null); - mv.visitCode(); - // REF_invokeStatic - mv.visitLdcInsn(handle1); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invoke", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "runStaticM", "()V", null, null); - mv.visitCode(); - // REF_invokeStatic - mv.visitLdcInsn(handle2); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invoke", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - - cw.visitEnd(); - return cw.toByteArray(); - } - static class CL extends ClassLoader { - @Override - protected Class findClass(String name) throws ClassNotFoundException { - byte[] classBytes = null; - switch (name) { - case "BadInterfaceMethodref": classBytes = dumpBadInterfaceMethodref(); break; - case "BadMethodref" : classBytes = dumpBadMethodref(); break; - case "IBad" : classBytes = dumpIBad(); break; - default : throw new ClassNotFoundException(name); - } - return defineClass(name, classBytes, 0, classBytes.length); - } - } - - public static void main(String[] args) throws Throwable { - try (FileOutputStream fos = new FileOutputStream("BadInterfaceMethodref.class")) { - fos.write(dumpBadInterfaceMethodref()); - } - try (FileOutputStream fos = new FileOutputStream("IBad.class")) { - fos.write(dumpIBad()); - } - try (FileOutputStream fos = new FileOutputStream("BadMethodref.class")) { - fos.write(dumpBadMethodref()); - } - - Class cls = (new CL()).loadClass("BadInterfaceMethodref"); - String[] methods = {"runm", "runStaticM"}; - System.out.println("Test BadInterfaceMethodref:"); - int success = 0; - for (String name : methods) { - try { - System.out.printf("invoke %s: \n", name); - cls.getMethod(name).invoke(cls.newInstance()); - System.out.println("FAILED (no exception)"); // ICCE should be thrown - } catch (Throwable e) { - if (e instanceof InvocationTargetException && e.getCause() != null && - e.getCause() instanceof IncompatibleClassChangeError) { - System.out.println("PASSED"); - success++; - continue; - } else { - System.out.println("FAILED with exception"); - throw e; - } - } - } - if (success != methods.length) { - throw new Exception("BadInterfaceMethodRef Failed to catch IncompatibleClassChangeError"); - } - System.out.println("Test BadMethodref:"); - cls = (new CL()).loadClass("BadMethodref"); - success = 0; - for (String name : methods) { - try { - System.out.printf("invoke %s: \n", name); - cls.getMethod(name).invoke(cls.newInstance()); - System.out.println("FAILED (no exception)"); // ICCE should be thrown - } catch (Throwable e) { - if (e instanceof InvocationTargetException && e.getCause() != null && - e.getCause() instanceof IncompatibleClassChangeError) { - System.out.println("PASSED"); - success++; - continue; - } else { - System.out.println("FAILED with exception"); - throw e; - } - } - } - if (success != methods.length) { - throw new Exception("BadMethodRef Failed to catch IncompatibleClassChangeError"); - } - - } -} diff -r 4cc9d7af1b01 -r 62db4b48cbef hotspot/test/runtime/8087223/IntfMethod.java --- a/hotspot/test/runtime/8087223/IntfMethod.java Thu Nov 19 11:54:32 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * $bug 8087223 - * @summary Adding constantTag to keep method call consistent with it. - * @compile -XDignore.symbol.file IntfMethod.java - * @run main/othervm IntfMethod - * @run main/othervm -Xint IntfMethod - * @run main/othervm -Xcomp IntfMethod - */ - - -import jdk.internal.org.objectweb.asm.*; -import java.io.FileOutputStream; -import java.lang.reflect.InvocationTargetException; -import static jdk.internal.org.objectweb.asm.Opcodes.*; - -public class IntfMethod { - static byte[] dumpC() { - ClassWriter cw = new ClassWriter(0); - cw.visit(52, ACC_PUBLIC | ACC_SUPER, "C", null, "java/lang/Object", new String[]{"I"}); - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "testSpecialIntf", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "I", "f1", "()V", /*itf=*/false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "testStaticIntf", "()V", null, null); - mv.visitCode(); - mv.visitMethodInsn(INVOKESTATIC, "I", "f2", "()V", /*itf=*/false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "testSpecialClass", "()V", null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "C", "f1", "()V", /*itf=*/true); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "f2", "()V", null, null); - mv.visitCode(); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 1); - mv.visitEnd(); - } - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "testStaticClass", "()V", null, null); - mv.visitCode(); - mv.visitMethodInsn(INVOKESTATIC, "C", "f2", "()V", /*itf=*/true); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - cw.visitEnd(); - return cw.toByteArray(); - } - - static byte[] dumpI() { - ClassWriter cw = new ClassWriter(0); - cw.visit(52, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, "I", null, "java/lang/Object", null); - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "f1", "()V", null, null); - mv.visitCode(); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 1); - mv.visitEnd(); - } - { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "f2", "()V", null, null); - mv.visitCode(); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 1); - mv.visitEnd(); - } - cw.visitEnd(); - return cw.toByteArray(); - } - - static class CL extends ClassLoader { - @Override - protected Class findClass(String name) throws ClassNotFoundException { - byte[] classFile; - switch (name) { - case "I": classFile = dumpI(); break; - case "C": classFile = dumpC(); break; - default: - throw new ClassNotFoundException(name); - } - return defineClass(name, classFile, 0, classFile.length); - } - } - - public static void main(String[] args) throws Throwable { - Class cls = (new CL()).loadClass("C"); - try (FileOutputStream fos = new FileOutputStream("I.class")) { fos.write(dumpI()); } - try (FileOutputStream fos = new FileOutputStream("C.class")) { fos.write(dumpC()); } - - int success = 0; - for (String name : new String[] { "testSpecialIntf", "testStaticIntf", "testSpecialClass", "testStaticClass"}) { - System.out.printf("%s: ", name); - try { - cls.getMethod(name).invoke(cls.newInstance()); - System.out.println("FAILED"); - } catch (Throwable e) { - if (e instanceof InvocationTargetException && - e.getCause() != null && e.getCause() instanceof IncompatibleClassChangeError) { - System.out.println("PASSED"); - success++; - continue; - } - } - } - if (success != 4) throw new Exception("Failed to catch ICCE"); - } -}