diff -r 70dab4a0cd45 -r bfe6be3c4ef8 hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Mon Apr 13 18:49:59 2015 -0700 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Apr 14 18:03:43 2015 +0300 @@ -2712,6 +2712,57 @@ return false; } +bool InstanceKlass::find_inner_classes_attr(instanceKlassHandle k, int* ooff, int* noff, TRAPS) { + constantPoolHandle i_cp(THREAD, k->constants()); + for (InnerClassesIterator iter(k); !iter.done(); iter.next()) { + int ioff = iter.inner_class_info_index(); + if (ioff != 0) { + // Check to see if the name matches the class we're looking for + // before attempting to find the class. + if (i_cp->klass_name_at_matches(k, ioff)) { + Klass* inner_klass = i_cp->klass_at(ioff, CHECK_false); + if (k() == inner_klass) { + *ooff = iter.outer_class_info_index(); + *noff = iter.inner_name_index(); + return true; + } + } + } + } + return false; +} + +Klass* InstanceKlass::compute_enclosing_class_impl(instanceKlassHandle k, bool* inner_is_member, TRAPS) { + instanceKlassHandle outer_klass; + *inner_is_member = false; + int ooff = 0, noff = 0; + if (find_inner_classes_attr(k, &ooff, &noff, THREAD)) { + constantPoolHandle i_cp(THREAD, k->constants()); + if (ooff != 0) { + Klass* ok = i_cp->klass_at(ooff, CHECK_NULL); + outer_klass = instanceKlassHandle(THREAD, ok); + *inner_is_member = true; + } + if (outer_klass.is_null()) { + // It may be anonymous; try for that. + int encl_method_class_idx = k->enclosing_method_class_index(); + if (encl_method_class_idx != 0) { + Klass* ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL); + outer_klass = instanceKlassHandle(THREAD, ok); + *inner_is_member = false; + } + } + } + + // If no inner class attribute found for this class. + if (outer_klass.is_null()) return NULL; + + // Throws an exception if outer klass has not declared k as an inner klass + // We need evidence that each klass knows about the other, or else + // the system could allow a spoof of an inner class to gain access rights. + Reflection::check_for_inner_class(outer_klass, k, *inner_is_member, CHECK_NULL); + return outer_klass(); +} jint InstanceKlass::compute_modifier_flags(TRAPS) const { jint access = access_flags().as_int();