Thu, 02 Feb 2017 00:29:28 +0000
8087342: Crash in klassItable::initialize_itable_for_interface
Summary: Fix method searches to handle static, private instance and overpass
Reviewed-by: acorn
1.1 --- a/src/share/vm/classfile/verifier.cpp Fri Jan 20 16:22:39 2017 +0000 1.2 +++ b/src/share/vm/classfile/verifier.cpp Thu Feb 02 00:29:28 2017 +0000 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -1969,7 +1969,7 @@ 1.11 InstanceKlass* target_instance = InstanceKlass::cast(target_class); 1.12 fieldDescriptor fd; 1.13 if (is_method) { 1.14 - Method* m = target_instance->uncached_lookup_method(field_name, field_sig, Klass::normal); 1.15 + Method* m = target_instance->uncached_lookup_method(field_name, field_sig, Klass::find_overpass); 1.16 if (m != NULL && m->is_protected()) { 1.17 if (!this_class->is_same_class_package(m->method_holder())) { 1.18 return true; 1.19 @@ -2539,7 +2539,7 @@ 1.20 Klass* ref_klass = load_class(ref_class_type.name(), CHECK); 1.21 Method* m = InstanceKlass::cast(ref_klass)->uncached_lookup_method( 1.22 vmSymbols::object_initializer_name(), 1.23 - cp->signature_ref_at(bcs->get_index_u2()), Klass::normal); 1.24 + cp->signature_ref_at(bcs->get_index_u2()), Klass::find_overpass); 1.25 // Do nothing if method is not found. Let resolution detect the error. 1.26 if (m != NULL) { 1.27 instanceKlassHandle mh(THREAD, m->method_holder());
2.1 --- a/src/share/vm/interpreter/linkResolver.cpp Fri Jan 20 16:22:39 2017 +0000 2.2 +++ b/src/share/vm/interpreter/linkResolver.cpp Thu Feb 02 00:29:28 2017 +0000 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -289,11 +289,11 @@ 2.11 // returns first instance method 2.12 // Looks up method in classes, then looks up local default methods 2.13 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { 2.14 - Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::normal); 2.15 + Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::find_overpass); 2.16 result = methodHandle(THREAD, result_oop); 2.17 while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) { 2.18 KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super()); 2.19 - result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal)); 2.20 + result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::find_overpass)); 2.21 } 2.22 2.23 if (klass->oop_is_array()) { 2.24 @@ -320,7 +320,9 @@ 2.25 // First check in default method array 2.26 if (!resolved_method->is_abstract() && 2.27 (InstanceKlass::cast(klass())->default_methods() != NULL)) { 2.28 - int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false, false); 2.29 + int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), 2.30 + name, signature, Klass::find_overpass, 2.31 + Klass::find_static, Klass::find_private); 2.32 if (index >= 0 ) { 2.33 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); 2.34 } 2.35 @@ -1184,7 +1186,7 @@ 2.36 assert(resolved_method->method_holder()->is_linked(), "must be linked"); 2.37 2.38 // do lookup based on receiver klass using the vtable index 2.39 - if (resolved_method->method_holder()->is_interface()) { // miranda method 2.40 + if (resolved_method->method_holder()->is_interface()) { // default or miranda method 2.41 vtable_index = vtable_index_of_interface_method(resolved_klass, 2.42 resolved_method); 2.43 assert(vtable_index >= 0 , "we should have valid vtable index at this point"); 2.44 @@ -1193,7 +1195,7 @@ 2.45 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); 2.46 } else { 2.47 // at this point we are sure that resolved_method is virtual and not 2.48 - // a miranda method; therefore, it must have a valid vtable index. 2.49 + // a default or miranda method; therefore, it must have a valid vtable index. 2.50 assert(!resolved_method->has_itable_index(), ""); 2.51 vtable_index = resolved_method->vtable_index(); 2.52 // We could get a negative vtable_index for final methods,
3.1 --- a/src/share/vm/oops/arrayKlass.cpp Fri Jan 20 16:22:39 2017 +0000 3.2 +++ b/src/share/vm/oops/arrayKlass.cpp Thu Feb 02 00:29:28 2017 +0000 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -71,10 +71,13 @@ 3.11 return super()->find_field(name, sig, fd); 3.12 } 3.13 3.14 -Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const { 3.15 +Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const { 3.16 // There are no methods in an array klass but the super class (Object) has some 3.17 assert(super(), "super klass must be present"); 3.18 - return super()->uncached_lookup_method(name, signature, mode); 3.19 + // Always ignore overpass methods in superclasses, although technically the 3.20 + // super klass of an array, (j.l.Object) should not have 3.21 + // any overpass methods present. 3.22 + return super()->uncached_lookup_method(name, signature, Klass::skip_overpass); 3.23 } 3.24 3.25 ArrayKlass::ArrayKlass(Symbol* name) {
4.1 --- a/src/share/vm/oops/arrayKlass.hpp Fri Jan 20 16:22:39 2017 +0000 4.2 +++ b/src/share/vm/oops/arrayKlass.hpp Thu Feb 02 00:29:28 2017 +0000 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -90,7 +90,7 @@ 4.11 Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; 4.12 4.13 // Lookup operations 4.14 - Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const; 4.15 + Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const; 4.16 4.17 // Casting from Klass* 4.18 static ArrayKlass* cast(Klass* k) {
5.1 --- a/src/share/vm/oops/instanceKlass.cpp Fri Jan 20 16:22:39 2017 +0000 5.2 +++ b/src/share/vm/oops/instanceKlass.cpp Thu Feb 02 00:29:28 2017 +0000 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -1475,18 +1475,23 @@ 5.11 5.12 // find_method looks up the name/signature in the local methods array 5.13 Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const { 5.14 - return find_method_impl(name, signature, false); 5.15 + return find_method_impl(name, signature, find_overpass, find_static, find_private); 5.16 } 5.17 5.18 -Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const { 5.19 - return InstanceKlass::find_method_impl(methods(), name, signature, skipping_overpass, false); 5.20 +Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, 5.21 + OverpassLookupMode overpass_mode, 5.22 + StaticLookupMode static_mode, 5.23 + PrivateLookupMode private_mode) const { 5.24 + return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode); 5.25 } 5.26 5.27 // find_instance_method looks up the name/signature in the local methods array 5.28 // and skips over static methods 5.29 Method* InstanceKlass::find_instance_method( 5.30 Array<Method*>* methods, Symbol* name, Symbol* signature) { 5.31 - Method* meth = InstanceKlass::find_method_impl(methods, name, signature, false, true); 5.32 + Method* meth = InstanceKlass::find_method_impl(methods, name, signature, 5.33 + find_overpass, skip_static, find_private); 5.34 + assert(((meth == NULL) || !meth->is_static()), "find_instance_method should have skipped statics"); 5.35 return meth; 5.36 } 5.37 5.38 @@ -1496,22 +1501,51 @@ 5.39 return InstanceKlass::find_instance_method(methods(), name, signature); 5.40 } 5.41 5.42 +// Find looks up the name/signature in the local methods array 5.43 +// and filters on the overpass, static and private flags 5.44 +// This returns the first one found 5.45 +// note that the local methods array can have up to one overpass, one static 5.46 +// and one instance (private or not) with the same name/signature 5.47 +Method* InstanceKlass::find_local_method(Symbol* name, Symbol* signature, 5.48 + OverpassLookupMode overpass_mode, 5.49 + StaticLookupMode static_mode, 5.50 + PrivateLookupMode private_mode) const { 5.51 + return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode); 5.52 +} 5.53 + 5.54 +// Find looks up the name/signature in the local methods array 5.55 +// and filters on the overpass, static and private flags 5.56 +// This returns the first one found 5.57 +// note that the local methods array can have up to one overpass, one static 5.58 +// and one instance (private or not) with the same name/signature 5.59 +Method* InstanceKlass::find_local_method(Array<Method*>* methods, 5.60 + Symbol* name, Symbol* signature, 5.61 + OverpassLookupMode overpass_mode, 5.62 + StaticLookupMode static_mode, 5.63 + PrivateLookupMode private_mode) { 5.64 + return InstanceKlass::find_method_impl(methods, name, signature, overpass_mode, static_mode, private_mode); 5.65 +} 5.66 + 5.67 + 5.68 // find_method looks up the name/signature in the local methods array 5.69 Method* InstanceKlass::find_method( 5.70 Array<Method*>* methods, Symbol* name, Symbol* signature) { 5.71 - return InstanceKlass::find_method_impl(methods, name, signature, false, false); 5.72 + return InstanceKlass::find_method_impl(methods, name, signature, find_overpass, find_static, find_private); 5.73 } 5.74 5.75 Method* InstanceKlass::find_method_impl( 5.76 - Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) { 5.77 - int hit = find_method_index(methods, name, signature, skipping_overpass, skipping_static); 5.78 + Array<Method*>* methods, Symbol* name, Symbol* signature, 5.79 + OverpassLookupMode overpass_mode, StaticLookupMode static_mode, 5.80 + PrivateLookupMode private_mode) { 5.81 + int hit = find_method_index(methods, name, signature, overpass_mode, static_mode, private_mode); 5.82 return hit >= 0 ? methods->at(hit): NULL; 5.83 } 5.84 5.85 -bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static) { 5.86 - return (m->signature() == signature) && 5.87 +bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static, bool skipping_private) { 5.88 + return ((m->signature() == signature) && 5.89 (!skipping_overpass || !m->is_overpass()) && 5.90 - (!skipping_static || !m->is_static()); 5.91 + (!skipping_static || !m->is_static()) && 5.92 + (!skipping_private || !m->is_private())); 5.93 } 5.94 5.95 // Used directly for default_methods to find the index into the 5.96 @@ -1521,15 +1555,25 @@ 5.97 // the search continues to find a potential non-overpass match. This capability 5.98 // is important during method resolution to prefer a static method, for example, 5.99 // over an overpass method. 5.100 +// There is the possibility in any _method's array to have the same name/signature 5.101 +// for a static method, an overpass method and a local instance method 5.102 +// To correctly catch a given method, the search criteria may need 5.103 +// to explicitly skip the other two. For local instance methods, it 5.104 +// is often necessary to skip private methods 5.105 int InstanceKlass::find_method_index( 5.106 - Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) { 5.107 + Array<Method*>* methods, Symbol* name, Symbol* signature, 5.108 + OverpassLookupMode overpass_mode, StaticLookupMode static_mode, 5.109 + PrivateLookupMode private_mode) { 5.110 + bool skipping_overpass = (overpass_mode == skip_overpass); 5.111 + bool skipping_static = (static_mode == skip_static); 5.112 + bool skipping_private = (private_mode == skip_private); 5.113 int hit = binary_search(methods, name); 5.114 if (hit != -1) { 5.115 Method* m = methods->at(hit); 5.116 5.117 // Do linear search to find matching signature. First, quick check 5.118 // for common case, ignoring overpasses if requested. 5.119 - if (method_matches(m, signature, skipping_overpass, skipping_static)) return hit; 5.120 + if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return hit; 5.121 5.122 // search downwards through overloaded methods 5.123 int i; 5.124 @@ -1537,18 +1581,18 @@ 5.125 Method* m = methods->at(i); 5.126 assert(m->is_method(), "must be method"); 5.127 if (m->name() != name) break; 5.128 - if (method_matches(m, signature, skipping_overpass, skipping_static)) return i; 5.129 + if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i; 5.130 } 5.131 // search upwards 5.132 for (i = hit + 1; i < methods->length(); ++i) { 5.133 Method* m = methods->at(i); 5.134 assert(m->is_method(), "must be method"); 5.135 if (m->name() != name) break; 5.136 - if (method_matches(m, signature, skipping_overpass, skipping_static)) return i; 5.137 + if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i; 5.138 } 5.139 // not found 5.140 #ifdef ASSERT 5.141 - int index = skipping_overpass || skipping_static ? -1 : linear_search(methods, name, signature); 5.142 + int index = (skipping_overpass || skipping_static || skipping_private) ? -1 : linear_search(methods, name, signature); 5.143 assert(index == -1, err_msg("binary search should have found entry %d", index)); 5.144 #endif 5.145 } 5.146 @@ -1574,16 +1618,16 @@ 5.147 5.148 // uncached_lookup_method searches both the local class methods array and all 5.149 // superclasses methods arrays, skipping any overpass methods in superclasses. 5.150 -Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const { 5.151 - MethodLookupMode lookup_mode = mode; 5.152 +Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const { 5.153 + OverpassLookupMode overpass_local_mode = overpass_mode; 5.154 Klass* klass = const_cast<InstanceKlass*>(this); 5.155 while (klass != NULL) { 5.156 - Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, (lookup_mode == skip_overpass)); 5.157 + Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, overpass_local_mode, find_static, find_private); 5.158 if (method != NULL) { 5.159 return method; 5.160 } 5.161 klass = InstanceKlass::cast(klass)->super(); 5.162 - lookup_mode = skip_overpass; // Always ignore overpass methods in superclasses 5.163 + overpass_local_mode = skip_overpass; // Always ignore overpass methods in superclasses 5.164 } 5.165 return NULL; 5.166 } 5.167 @@ -1613,7 +1657,7 @@ 5.168 } 5.169 // Look up interfaces 5.170 if (m == NULL) { 5.171 - m = lookup_method_in_all_interfaces(name, signature, normal); 5.172 + m = lookup_method_in_all_interfaces(name, signature, find_defaults); 5.173 } 5.174 return m; 5.175 } 5.176 @@ -1623,7 +1667,7 @@ 5.177 // They should only be found in the initial InterfaceMethodRef 5.178 Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name, 5.179 Symbol* signature, 5.180 - MethodLookupMode mode) const { 5.181 + DefaultsLookupMode defaults_mode) const { 5.182 Array<Klass*>* all_ifs = transitive_interfaces(); 5.183 int num_ifs = all_ifs->length(); 5.184 InstanceKlass *ik = NULL; 5.185 @@ -1631,7 +1675,7 @@ 5.186 ik = InstanceKlass::cast(all_ifs->at(i)); 5.187 Method* m = ik->lookup_method(name, signature); 5.188 if (m != NULL && m->is_public() && !m->is_static() && 5.189 - ((mode != skip_defaults) || !m->is_default_method())) { 5.190 + ((defaults_mode != skip_defaults) || !m->is_default_method())) { 5.191 return m; 5.192 } 5.193 }
6.1 --- a/src/share/vm/oops/instanceKlass.hpp Fri Jan 20 16:22:39 2017 +0000 6.2 +++ b/src/share/vm/oops/instanceKlass.hpp Thu Feb 02 00:29:28 2017 +0000 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -527,18 +527,36 @@ 6.11 Method* find_instance_method(Symbol* name, Symbol* signature); 6.12 static Method* find_instance_method(Array<Method*>* methods, Symbol* name, Symbol* signature); 6.13 6.14 + // find a local method (returns NULL if not found) 6.15 + Method* find_local_method(Symbol* name, Symbol* signature, 6.16 + OverpassLookupMode overpass_mode, 6.17 + StaticLookupMode static_mode, 6.18 + PrivateLookupMode private_mode) const; 6.19 + 6.20 + // find a local method from given methods array (returns NULL if not found) 6.21 + static Method* find_local_method(Array<Method*>* methods, 6.22 + Symbol* name, Symbol* signature, 6.23 + OverpassLookupMode overpass_mode, 6.24 + StaticLookupMode static_mode, 6.25 + PrivateLookupMode private_mode); 6.26 + 6.27 // true if method matches signature and conforms to skipping_X conditions. 6.28 - static bool method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static); 6.29 + static bool method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static, bool skipping_private); 6.30 6.31 - // find a local method index in default_methods (returns -1 if not found) 6.32 - static int find_method_index(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static); 6.33 + // find a local method index in methods or default_methods (returns -1 if not found) 6.34 + static int find_method_index(Array<Method*>* methods, 6.35 + Symbol* name, Symbol* signature, 6.36 + OverpassLookupMode overpass_mode, 6.37 + StaticLookupMode static_mode, 6.38 + PrivateLookupMode private_mode); 6.39 + 6.40 6.41 // lookup operation (returns NULL if not found) 6.42 - Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const; 6.43 + Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const; 6.44 6.45 // lookup a method in all the interfaces that this class implements 6.46 // (returns NULL if not found) 6.47 - Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature, MethodLookupMode mode) const; 6.48 + Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature, DefaultsLookupMode defaults_mode) const; 6.49 6.50 // lookup a method in local defaults then in all interfaces 6.51 // (returns NULL if not found) 6.52 @@ -1089,8 +1107,15 @@ 6.53 Klass* array_klass_impl(bool or_null, TRAPS); 6.54 6.55 // find a local method (returns NULL if not found) 6.56 - Method* find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const; 6.57 - static Method* find_method_impl(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static); 6.58 + Method* find_method_impl(Symbol* name, Symbol* signature, 6.59 + OverpassLookupMode overpass_mode, 6.60 + StaticLookupMode static_mode, 6.61 + PrivateLookupMode private_mode) const; 6.62 + static Method* find_method_impl(Array<Method*>* methods, 6.63 + Symbol* name, Symbol* signature, 6.64 + OverpassLookupMode overpass_mode, 6.65 + StaticLookupMode static_mode, 6.66 + PrivateLookupMode private_mode); 6.67 6.68 // Free CHeap allocated fields. 6.69 void release_C_heap_structures();
7.1 --- a/src/share/vm/oops/klass.cpp Fri Jan 20 16:22:39 2017 +0000 7.2 +++ b/src/share/vm/oops/klass.cpp Thu Feb 02 00:29:28 2017 +0000 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -140,7 +140,7 @@ 7.11 return NULL; 7.12 } 7.13 7.14 -Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const { 7.15 +Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const { 7.16 #ifdef ASSERT 7.17 tty->print_cr("Error: uncached_lookup_method called on a klass oop." 7.18 " Likely error: reflection method does not correctly"
8.1 --- a/src/share/vm/oops/klass.hpp Fri Jan 20 16:22:39 2017 +0000 8.2 +++ b/src/share/vm/oops/klass.hpp Thu Feb 02 00:29:28 2017 +0000 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -192,7 +192,10 @@ 8.11 void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw(); 8.12 8.13 public: 8.14 - enum MethodLookupMode { normal, skip_overpass, skip_defaults }; 8.15 + enum DefaultsLookupMode { find_defaults, skip_defaults }; 8.16 + enum OverpassLookupMode { find_overpass, skip_overpass }; 8.17 + enum StaticLookupMode { find_static, skip_static }; 8.18 + enum PrivateLookupMode { find_private, skip_private }; 8.19 8.20 bool is_klass() const volatile { return true; } 8.21 8.22 @@ -458,10 +461,10 @@ 8.23 // lookup operation for MethodLookupCache 8.24 friend class MethodLookupCache; 8.25 virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const; 8.26 - virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const; 8.27 + virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const; 8.28 public: 8.29 Method* lookup_method(Symbol* name, Symbol* signature) const { 8.30 - return uncached_lookup_method(name, signature, normal); 8.31 + return uncached_lookup_method(name, signature, find_overpass); 8.32 } 8.33 8.34 // array class with specific rank
9.1 --- a/src/share/vm/oops/klassVtable.cpp Fri Jan 20 16:22:39 2017 +0000 9.2 +++ b/src/share/vm/oops/klassVtable.cpp Thu Feb 02 00:29:28 2017 +0000 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. 9.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -696,7 +696,7 @@ 9.11 // this check for all access permissions. 9.12 InstanceKlass *sk = InstanceKlass::cast(super); 9.13 if (sk->has_miranda_methods()) { 9.14 - if (sk->lookup_method_in_all_interfaces(name, signature, Klass::normal) != NULL) { 9.15 + if (sk->lookup_method_in_all_interfaces(name, signature, Klass::find_defaults) != NULL) { 9.16 return false; // found a matching miranda; we do not need a new entry 9.17 } 9.18 } 9.19 @@ -729,7 +729,6 @@ 9.20 if (mhk->is_interface()) { 9.21 assert(m->is_public(), "should be public"); 9.22 assert(ik()->implements_interface(method_holder) , "this class should implement the interface"); 9.23 - // the search could find a miranda or a default method 9.24 if (is_miranda(m, ik()->methods(), ik()->default_methods(), ik()->super())) { 9.25 return true; 9.26 } 9.27 @@ -737,25 +736,57 @@ 9.28 return false; 9.29 } 9.30 9.31 -// check if a method is a miranda method, given a class's methods table, 9.32 -// its default_method table and its super 9.33 -// Miranda methods are calculated twice: 9.34 -// first: before vtable size calculation: including abstract and superinterface default 9.35 +// Check if a method is a miranda method, given a class's methods array, 9.36 +// its default_method table and its super class. 9.37 +// "Miranda" means an abstract non-private method that would not be 9.38 +// overridden for the local class. 9.39 +// A "miranda" method should only include non-private interface 9.40 +// instance methods, i.e. not private methods, not static methods, 9.41 +// not default methods (concrete interface methods), not overpass methods. 9.42 +// If a given class already has a local (including overpass) method, a 9.43 +// default method, or any of its superclasses has the same which would have 9.44 +// overridden an abstract method, then this is not a miranda method. 9.45 +// 9.46 +// Miranda methods are checked multiple times. 9.47 +// Pass 1: during class load/class file parsing: before vtable size calculation: 9.48 +// include superinterface abstract and default methods (non-private instance). 9.49 // We include potential default methods to give them space in the vtable. 9.50 -// During the first run, the default_methods list is empty 9.51 -// This is seen by default method creation 9.52 -// Second: recalculated during vtable initialization: only include abstract methods. 9.53 +// During the first run, the current instanceKlass has not yet been 9.54 +// created, the superclasses and superinterfaces do have instanceKlasses 9.55 +// but may not have vtables, the default_methods list is empty, no overpasses. 9.56 +// This is seen by default method creation. 9.57 +// 9.58 +// Pass 2: recalculated during vtable initialization: only include abstract methods. 9.59 +// The goal of pass 2 is to walk through the superinterfaces to see if any of 9.60 +// the superinterface methods (which were all abstract pre-default methods) 9.61 +// need to be added to the vtable. 9.62 +// With the addition of default methods, we have three new challenges: 9.63 +// overpasses, static interface methods and private interface methods. 9.64 +// Static and private interface methods do not get added to the vtable and 9.65 +// are not seen by the method resolution process, so we skip those. 9.66 +// Overpass methods are already in the vtable, so vtable lookup will 9.67 +// find them and we don't need to add a miranda method to the end of 9.68 +// the vtable. So we look for overpass methods and if they are found we 9.69 +// return false. Note that we inherit our superclasses vtable, so 9.70 +// the superclass' search also needs to use find_overpass so that if 9.71 +// one is found we return false. 9.72 +// False means - we don't need a miranda method added to the vtable. 9.73 +// 9.74 // During the second run, default_methods is set up, so concrete methods from 9.75 // superinterfaces with matching names/signatures to default_methods are already 9.76 // in the default_methods list and do not need to be appended to the vtable 9.77 -// as mirandas 9.78 -// This is seen by link resolution and selection. 9.79 -// "miranda" means not static, not defined by this class. 9.80 -// private methods in interfaces do not belong in the miranda list. 9.81 -// the caller must make sure that the method belongs to an interface implemented by the class 9.82 -// Miranda methods only include public interface instance methods 9.83 -// Not private methods, not static methods, not default == concrete abstract 9.84 -// Miranda methods also do not include overpass methods in interfaces 9.85 +// as mirandas. Abstract methods may already have been handled via 9.86 +// overpasses - either local or superclass overpasses, which may be 9.87 +// in the vtable already. 9.88 +// 9.89 +// Pass 3: They are also checked by link resolution and selection, 9.90 +// for invocation on a method (not interface method) reference that 9.91 +// resolves to a method with an interface as its method_holder. 9.92 +// Used as part of walking from the bottom of the vtable to find 9.93 +// the vtable index for the miranda method. 9.94 +// 9.95 +// Part of the Miranda Rights in the US mean that if you do not have 9.96 +// an attorney one will be appointed for you. 9.97 bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, 9.98 Array<Method*>* default_methods, Klass* super) { 9.99 if (m->is_static() || m->is_private() || m->is_overpass()) { 9.100 @@ -763,44 +794,36 @@ 9.101 } 9.102 Symbol* name = m->name(); 9.103 Symbol* signature = m->signature(); 9.104 - Method* mo; 9.105 9.106 - if ((mo = InstanceKlass::find_instance_method(class_methods, name, signature)) == NULL) { 9.107 - // did not find it in the method table of the current class 9.108 - if ((default_methods == NULL) || 9.109 - InstanceKlass::find_method(default_methods, name, signature) == NULL) { 9.110 - if (super == NULL) { 9.111 - // super doesn't exist 9.112 - return true; 9.113 - } 9.114 - 9.115 - mo = InstanceKlass::cast(super)->lookup_method(name, signature); 9.116 - while (mo != NULL && mo->access_flags().is_static() 9.117 - && mo->method_holder() != NULL 9.118 - && mo->method_holder()->super() != NULL) 9.119 - { 9.120 - mo = mo->method_holder()->super()->uncached_lookup_method(name, signature, Klass::normal); 9.121 - } 9.122 - if (mo == NULL || mo->access_flags().is_private() ) { 9.123 - // super class hierarchy does not implement it or protection is different 9.124 - return true; 9.125 - } 9.126 - } 9.127 - } else { 9.128 - // if the local class has a private method, the miranda will not 9.129 - // override it, so a vtable slot is needed 9.130 - if (mo->access_flags().is_private()) { 9.131 - 9.132 - // Second round, weed out any superinterface methods that turned 9.133 - // into default methods, i.e. were concrete not abstract in the end 9.134 - if ((default_methods == NULL) || 9.135 - InstanceKlass::find_method(default_methods, name, signature) == NULL) { 9.136 - return true; 9.137 - } 9.138 - } 9.139 + // First look in local methods to see if already covered 9.140 + if (InstanceKlass::find_local_method(class_methods, name, signature, 9.141 + Klass::find_overpass, Klass::skip_static, Klass::skip_private) != NULL) 9.142 + { 9.143 + return false; 9.144 } 9.145 9.146 - return false; 9.147 + // Check local default methods 9.148 + if ((default_methods != NULL) && 9.149 + (InstanceKlass::find_method(default_methods, name, signature) != NULL)) 9.150 + { 9.151 + return false; 9.152 + } 9.153 + 9.154 + InstanceKlass* cursuper; 9.155 + // Iterate on all superclasses, which should have instanceKlasses 9.156 + // Note that we explicitly look for overpasses at each level. 9.157 + // Overpasses may or may not exist for supers for pass 1, 9.158 + // they should have been created for pass 2 and later. 9.159 + 9.160 + for (cursuper = InstanceKlass::cast(super); cursuper != NULL; cursuper = (InstanceKlass*)cursuper->super()) 9.161 + { 9.162 + if (cursuper->find_local_method(name, signature, 9.163 + Klass::find_overpass, Klass::skip_static, Klass::skip_private) != NULL) { 9.164 + return false; 9.165 + } 9.166 + } 9.167 + 9.168 + return true; 9.169 } 9.170 9.171 // Scans current_interface_methods for miranda methods that do not 9.172 @@ -836,7 +859,7 @@ 9.173 if (is_miranda(im, class_methods, default_methods, super)) { // is it a miranda at all? 9.174 InstanceKlass *sk = InstanceKlass::cast(super); 9.175 // check if it is a duplicate of a super's miranda 9.176 - if (sk->lookup_method_in_all_interfaces(im->name(), im->signature(), Klass::normal) == NULL) { 9.177 + if (sk->lookup_method_in_all_interfaces(im->name(), im->signature(), Klass::find_defaults) == NULL) { 9.178 new_mirandas->append(im); 9.179 } 9.180 if (all_mirandas != NULL) {
10.1 --- a/src/share/vm/prims/jvm.cpp Fri Jan 20 16:22:39 2017 +0000 10.2 +++ b/src/share/vm/prims/jvm.cpp Thu Feb 02 00:29:28 2017 +0000 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 10.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -1346,7 +1346,7 @@ 10.11 Method* m_oop = object->klass()->uncached_lookup_method( 10.12 vmSymbols::run_method_name(), 10.13 vmSymbols::void_object_signature(), 10.14 - Klass::normal); 10.15 + Klass::find_overpass); 10.16 methodHandle m (THREAD, m_oop); 10.17 if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static()) { 10.18 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method");
11.1 --- a/src/share/vm/prims/nativeLookup.cpp Fri Jan 20 16:22:39 2017 +0000 11.2 +++ b/src/share/vm/prims/nativeLookup.cpp Thu Feb 02 00:29:28 2017 +0000 11.3 @@ -1,5 +1,5 @@ 11.4 /* 11.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 11.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 11.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.8 * 11.9 * This code is free software; you can redistribute it and/or modify it 11.10 @@ -408,7 +408,7 @@ 11.11 11.12 // Find method and invoke standard lookup 11.13 methodHandle method (THREAD, 11.14 - klass->uncached_lookup_method(m_name, s_name, Klass::normal)); 11.15 + klass->uncached_lookup_method(m_name, s_name, Klass::find_overpass)); 11.16 address result = lookup(method, in_base_library, CATCH); 11.17 assert(in_base_library, "must be in basic library"); 11.18 guarantee(result != NULL, "must be non NULL");
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/test/runtime/lambda-features/TestStaticandInstance.java Thu Feb 02 00:29:28 2017 +0000 12.3 @@ -0,0 +1,272 @@ 12.4 +/* 12.5 + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. 12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.7 + * 12.8 + * This code is free software; you can redistribute it and/or modify it 12.9 + * under the terms of the GNU General Public License version 2 only, as 12.10 + * published by the Free Software Foundation. 12.11 + * 12.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 12.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12.15 + * version 2 for more details (a copy is included in the LICENSE file that 12.16 + * accompanied this code). 12.17 + * 12.18 + * You should have received a copy of the GNU General Public License version 12.19 + * 2 along with this work; if not, write to the Free Software Foundation, 12.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 12.21 + * 12.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 12.23 + * or visit www.oracle.com if you need additional information or have any 12.24 + * questions. 12.25 + * 12.26 + */ 12.27 + 12.28 +/* 12.29 + * @test 12.30 + * @bug 8087342 12.31 + * @summary Test linkresolver search static, instance and overpass duplicates 12.32 + * @run main/othervm -Xverify:none TestStaticandInstance 12.33 + */ 12.34 + 12.35 + 12.36 +import java.util.*; 12.37 +import jdk.internal.org.objectweb.asm.*; 12.38 +import static jdk.internal.org.objectweb.asm.Opcodes.*; 12.39 + 12.40 +public class TestStaticandInstance { 12.41 + static final String stringC = "C"; 12.42 + static final String stringD = "D"; 12.43 + static final String stringI = "I"; 12.44 + 12.45 + public static void main(String args[]) throws Throwable { 12.46 + ClassLoader cl = new ClassLoader() { 12.47 + public Class<?> loadClass(String name) throws ClassNotFoundException { 12.48 + Class retClass; 12.49 + if ((retClass = findLoadedClass(name)) != null) { 12.50 + return retClass; 12.51 + } 12.52 + if (stringC.equals(name)) { 12.53 + byte[] classFile=dumpC(); 12.54 + return defineClass(stringC, classFile, 0, classFile.length); 12.55 + } 12.56 + if (stringD.equals(name)) { 12.57 + byte[] classFile=dumpD(); 12.58 + return defineClass(stringD, classFile, 0, classFile.length); 12.59 + } 12.60 + if (stringI.equals(name)) { 12.61 + byte[] classFile=dumpI(); 12.62 + return defineClass(stringI, classFile, 0, classFile.length); 12.63 + } 12.64 + return super.loadClass(name); 12.65 + } 12.66 + }; 12.67 + 12.68 + Class classC = cl.loadClass(stringC); 12.69 + Class classI = cl.loadClass(stringI); 12.70 + 12.71 + try { 12.72 + int staticret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallStatic").invoke(null); 12.73 + if (staticret != 1) { 12.74 + throw new RuntimeException("invokestatic failed to call correct method"); 12.75 + } 12.76 + System.out.println("staticret: " + staticret); // should be 1 12.77 + 12.78 + int invokeinterfaceret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallInterface").invoke(null); 12.79 + if (invokeinterfaceret != 0) { 12.80 + throw new RuntimeException(String.format("Expected java.lang.AbstractMethodError, got %d", invokeinterfaceret)); 12.81 + } 12.82 + System.out.println("invokeinterfaceret: AbstractMethodError"); 12.83 + 12.84 + int invokevirtualret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallVirtual").invoke(null); 12.85 + if (invokevirtualret != 0) { 12.86 + throw new RuntimeException(String.format("Expected java.lang.IncompatibleClassChangeError, got %d", invokevirtualret)); 12.87 + } 12.88 + System.out.println("invokevirtualret: IncompatibleClassChangeError"); 12.89 + } catch (java.lang.Throwable e) { 12.90 + throw new RuntimeException("Unexpected exception: " + e.getMessage()); 12.91 + } 12.92 + } 12.93 + 12.94 +/* 12.95 +interface I { 12.96 + public int m(); // abstract 12.97 + default int q() { return 3; } // trigger defmeth processing: C gets AME overpass 12.98 +} 12.99 + 12.100 +// C gets static, private and AME overpass m()I with -Xverify:none 12.101 +class C implements I { 12.102 + static int m() { return 1;} // javac with "n()" and patch to "m()" 12.103 + private int m() { return 2;} // javac with public and patch to private 12.104 +} 12.105 + 12.106 +public class D { 12.107 + public static int CallStatic() { 12.108 + int staticret = C.m(); // javac with "C.n" and patch to "C.m" 12.109 + return staticret; 12.110 + } 12.111 + public static int CallInterface() throws AbstractMethodError{ 12.112 + try { 12.113 + I myI = new C(); 12.114 + return myI.m(); 12.115 + } catch (java.lang.AbstractMethodError e) { 12.116 + return 0; // for success 12.117 + } 12.118 + } 12.119 + public static int CallVirtual() { 12.120 + try { 12.121 + C myC = new C(); 12.122 + return myC.m(); 12.123 + } catch (java.lang.IncompatibleClassChangeError e) { 12.124 + return 0; // for success 12.125 + } 12.126 + } 12.127 +} 12.128 +*/ 12.129 + 12.130 + public static byte[] dumpC() { 12.131 + 12.132 + ClassWriter cw = new ClassWriter(0); 12.133 + FieldVisitor fv; 12.134 + MethodVisitor mv; 12.135 + AnnotationVisitor av0; 12.136 + 12.137 + cw.visit(52, ACC_SUPER, "C", null, "java/lang/Object", new String[] { "I" }); 12.138 + 12.139 + { 12.140 + mv = cw.visitMethod(0, "<init>", "()V", null, null); 12.141 + mv.visitCode(); 12.142 + mv.visitVarInsn(ALOAD, 0); 12.143 + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); 12.144 + mv.visitInsn(RETURN); 12.145 + mv.visitMaxs(1, 1); 12.146 + mv.visitEnd(); 12.147 + } 12.148 + { 12.149 + mv = cw.visitMethod(ACC_STATIC, "m", "()I", null, null); 12.150 + mv.visitCode(); 12.151 + mv.visitInsn(ICONST_1); 12.152 + mv.visitInsn(IRETURN); 12.153 + mv.visitMaxs(1, 0); 12.154 + mv.visitEnd(); 12.155 + } 12.156 + { 12.157 + mv = cw.visitMethod(ACC_PRIVATE, "m", "()I", null, null); 12.158 + mv.visitCode(); 12.159 + mv.visitInsn(ICONST_2); 12.160 + mv.visitInsn(IRETURN); 12.161 + mv.visitMaxs(1, 1); 12.162 + mv.visitEnd(); 12.163 + } 12.164 + cw.visitEnd(); 12.165 + 12.166 + return cw.toByteArray(); 12.167 + } 12.168 + 12.169 + public static byte[] dumpD () { 12.170 + 12.171 + ClassWriter cw = new ClassWriter(0); 12.172 + FieldVisitor fv; 12.173 + MethodVisitor mv; 12.174 + AnnotationVisitor av0; 12.175 + 12.176 + cw.visit(52, ACC_PUBLIC + ACC_SUPER, "D", null, "java/lang/Object", null); 12.177 + 12.178 + { 12.179 + mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); 12.180 + mv.visitCode(); 12.181 + mv.visitVarInsn(ALOAD, 0); 12.182 + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); 12.183 + mv.visitInsn(RETURN); 12.184 + mv.visitMaxs(1, 1); 12.185 + mv.visitEnd(); 12.186 + } 12.187 + { 12.188 + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallStatic", "()I", null, null); 12.189 + mv.visitCode(); 12.190 + mv.visitMethodInsn(INVOKESTATIC, "C", "m", "()I", false); 12.191 + mv.visitVarInsn(ISTORE, 0); 12.192 + mv.visitVarInsn(ILOAD, 0); 12.193 + mv.visitInsn(IRETURN); 12.194 + mv.visitMaxs(1, 1); 12.195 + mv.visitEnd(); 12.196 + } 12.197 + { 12.198 + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallInterface", "()I", null, new String[] { "java/lang/AbstractMethodError" }); 12.199 + mv.visitCode(); 12.200 + Label l0 = new Label(); 12.201 + Label l1 = new Label(); 12.202 + Label l2 = new Label(); 12.203 + mv.visitTryCatchBlock(l0, l1, l2, "java/lang/AbstractMethodError"); 12.204 + mv.visitLabel(l0); 12.205 + mv.visitTypeInsn(NEW, "C"); 12.206 + mv.visitInsn(DUP); 12.207 + mv.visitMethodInsn(INVOKESPECIAL, "C", "<init>", "()V", false); 12.208 + mv.visitVarInsn(ASTORE, 0); 12.209 + mv.visitVarInsn(ALOAD, 0); 12.210 + mv.visitMethodInsn(INVOKEINTERFACE, "I", "m", "()I", true); 12.211 + mv.visitLabel(l1); 12.212 + mv.visitInsn(IRETURN); 12.213 + mv.visitLabel(l2); 12.214 + mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/AbstractMethodError"}); 12.215 + mv.visitVarInsn(ASTORE, 0); 12.216 + mv.visitInsn(ICONST_0); 12.217 + mv.visitInsn(IRETURN); 12.218 + mv.visitMaxs(2, 1); 12.219 + mv.visitEnd(); 12.220 + } 12.221 + { 12.222 + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallVirtual", "()I", null, null); 12.223 + mv.visitCode(); 12.224 + Label l0 = new Label(); 12.225 + Label l1 = new Label(); 12.226 + Label l2 = new Label(); 12.227 + mv.visitTryCatchBlock(l0, l1, l2, "java/lang/IncompatibleClassChangeError"); 12.228 + mv.visitLabel(l0); 12.229 + mv.visitTypeInsn(NEW, "C"); 12.230 + mv.visitInsn(DUP); 12.231 + mv.visitMethodInsn(INVOKESPECIAL, "C", "<init>", "()V", false); 12.232 + mv.visitVarInsn(ASTORE, 0); 12.233 + mv.visitVarInsn(ALOAD, 0); 12.234 + mv.visitMethodInsn(INVOKEVIRTUAL, "C", "m", "()I", false); 12.235 + mv.visitLabel(l1); 12.236 + mv.visitInsn(IRETURN); 12.237 + mv.visitLabel(l2); 12.238 + mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/IncompatibleClassChangeError"}); 12.239 + mv.visitVarInsn(ASTORE, 0); 12.240 + mv.visitInsn(ICONST_0); 12.241 + mv.visitInsn(IRETURN); 12.242 + mv.visitMaxs(2, 1); 12.243 + mv.visitEnd(); 12.244 + } 12.245 + cw.visitEnd(); 12.246 + 12.247 + return cw.toByteArray(); 12.248 + } 12.249 + 12.250 + public static byte[] dumpI() { 12.251 + 12.252 + ClassWriter cw = new ClassWriter(0); 12.253 + FieldVisitor fv; 12.254 + MethodVisitor mv; 12.255 + AnnotationVisitor av0; 12.256 + 12.257 + cw.visit(52, ACC_ABSTRACT + ACC_INTERFACE, "I", null, "java/lang/Object", null); 12.258 + 12.259 + { 12.260 + mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "m", "()I", null, null); 12.261 + mv.visitEnd(); 12.262 + } 12.263 + { 12.264 + mv = cw.visitMethod(ACC_PUBLIC, "q", "()I", null, null); 12.265 + mv.visitCode(); 12.266 + mv.visitInsn(ICONST_3); 12.267 + mv.visitInsn(IRETURN); 12.268 + mv.visitMaxs(1, 1); 12.269 + mv.visitEnd(); 12.270 + } 12.271 + cw.visitEnd(); 12.272 + 12.273 + return cw.toByteArray(); 12.274 + } 12.275 +}