1.1 --- a/src/share/vm/oops/instanceKlass.hpp Fri Mar 09 13:34:45 2012 -0800 1.2 +++ b/src/share/vm/oops/instanceKlass.hpp Tue Mar 13 13:50:48 2012 -0400 1.3 @@ -188,7 +188,17 @@ 1.4 klassOop _host_klass; 1.5 // Class signers. 1.6 objArrayOop _signers; 1.7 - // inner_classes attribute. 1.8 + // The InnerClasses attribute and EnclosingMethod attribute. The 1.9 + // _inner_classes is an array of shorts. If the class has InnerClasses 1.10 + // attribute, then the _inner_classes array begins with 4-tuples of shorts 1.11 + // [inner_class_info_index, outer_class_info_index, 1.12 + // inner_name_index, inner_class_access_flags] for the InnerClasses 1.13 + // attribute. If the EnclosingMethod attribute exists, it occupies the 1.14 + // last two shorts [class_index, method_index] of the array. If only 1.15 + // the InnerClasses attribute exists, the _inner_classes array length is 1.16 + // number_of_inner_classes * 4. If the class has both InnerClasses 1.17 + // and EnclosingMethod attributes the _inner_classes array length is 1.18 + // number_of_inner_classes * 4 + enclosing_method_attribute_size. 1.19 typeArrayOop _inner_classes; 1.20 // Implementors of this interface (not valid if it overflows) 1.21 klassOop _implementors[implementors_limit]; 1.22 @@ -251,8 +261,6 @@ 1.23 // Array of interesting part(s) of the previous version(s) of this 1.24 // instanceKlass. See PreviousVersionWalker below. 1.25 GrowableArray<PreviousVersionNode *>* _previous_versions; 1.26 - u2 _enclosing_method_class_index; // Constant pool index for class of enclosing method, or 0 if none 1.27 - u2 _enclosing_method_method_index; // Constant pool index for name and type of enclosing method, or 0 if none 1.28 // JVMTI fields can be moved to their own structure - see 6315920 1.29 unsigned char * _cached_class_file_bytes; // JVMTI: cached class file, before retransformable agent modified it in CFLH 1.30 jint _cached_class_file_len; // JVMTI: length of above 1.31 @@ -351,6 +359,12 @@ 1.32 inner_class_next_offset = 4 1.33 }; 1.34 1.35 + enum EnclosingMethodAttributeOffset { 1.36 + enclosing_method_class_index_offset = 0, 1.37 + enclosing_method_method_index_offset = 1, 1.38 + enclosing_method_attribute_size = 2 1.39 + }; 1.40 + 1.41 // method override check 1.42 bool is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS); 1.43 1.44 @@ -533,11 +547,15 @@ 1.45 Symbol* generic_signature() const { return _generic_signature; } 1.46 void set_generic_signature(Symbol* sig) { _generic_signature = sig; } 1.47 1.48 - u2 enclosing_method_class_index() const { return _enclosing_method_class_index; } 1.49 - u2 enclosing_method_method_index() const { return _enclosing_method_method_index; } 1.50 + u2 enclosing_method_data(int offset); 1.51 + u2 enclosing_method_class_index() { 1.52 + return enclosing_method_data(enclosing_method_class_index_offset); 1.53 + } 1.54 + u2 enclosing_method_method_index() { 1.55 + return enclosing_method_data(enclosing_method_method_index_offset); 1.56 + } 1.57 void set_enclosing_method_indices(u2 class_index, 1.58 - u2 method_index) { _enclosing_method_class_index = class_index; 1.59 - _enclosing_method_method_index = method_index; } 1.60 + u2 method_index); 1.61 1.62 // jmethodID support 1.63 static jmethodID get_jmethod_id(instanceKlassHandle ik_h, 1.64 @@ -1053,4 +1071,83 @@ 1.65 nmethod* get_nmethod() { return _nmethod; } 1.66 }; 1.67 1.68 +// An iterator that's used to access the inner classes indices in the 1.69 +// instanceKlass::_inner_classes array. 1.70 +class InnerClassesIterator : public StackObj { 1.71 + private: 1.72 + typeArrayHandle _inner_classes; 1.73 + int _length; 1.74 + int _idx; 1.75 + public: 1.76 + 1.77 + InnerClassesIterator(instanceKlassHandle k) { 1.78 + _inner_classes = k->inner_classes(); 1.79 + if (k->inner_classes() != NULL) { 1.80 + _length = _inner_classes->length(); 1.81 + // The inner class array's length should be the multiple of 1.82 + // inner_class_next_offset if it only contains the InnerClasses 1.83 + // attribute data, or it should be 1.84 + // n*inner_class_next_offset+enclosing_method_attribute_size 1.85 + // if it also contains the EnclosingMethod data. 1.86 + assert((_length % instanceKlass::inner_class_next_offset == 0 || 1.87 + _length % instanceKlass::inner_class_next_offset == instanceKlass::enclosing_method_attribute_size), 1.88 + "just checking"); 1.89 + // Remove the enclosing_method portion if exists. 1.90 + if (_length % instanceKlass::inner_class_next_offset == instanceKlass::enclosing_method_attribute_size) { 1.91 + _length -= instanceKlass::enclosing_method_attribute_size; 1.92 + } 1.93 + } else { 1.94 + _length = 0; 1.95 + } 1.96 + _idx = 0; 1.97 + } 1.98 + 1.99 + int length() const { 1.100 + return _length; 1.101 + } 1.102 + 1.103 + void next() { 1.104 + _idx += instanceKlass::inner_class_next_offset; 1.105 + } 1.106 + 1.107 + bool done() const { 1.108 + return (_idx >= _length); 1.109 + } 1.110 + 1.111 + u2 inner_class_info_index() const { 1.112 + return _inner_classes->ushort_at( 1.113 + _idx + instanceKlass::inner_class_inner_class_info_offset); 1.114 + } 1.115 + 1.116 + void set_inner_class_info_index(u2 index) { 1.117 + _inner_classes->ushort_at_put( 1.118 + _idx + instanceKlass::inner_class_inner_class_info_offset, index); 1.119 + } 1.120 + 1.121 + u2 outer_class_info_index() const { 1.122 + return _inner_classes->ushort_at( 1.123 + _idx + instanceKlass::inner_class_outer_class_info_offset); 1.124 + } 1.125 + 1.126 + void set_outer_class_info_index(u2 index) { 1.127 + _inner_classes->ushort_at_put( 1.128 + _idx + instanceKlass::inner_class_outer_class_info_offset, index); 1.129 + } 1.130 + 1.131 + u2 inner_name_index() const { 1.132 + return _inner_classes->ushort_at( 1.133 + _idx + instanceKlass::inner_class_inner_name_offset); 1.134 + } 1.135 + 1.136 + void set_inner_name_index(u2 index) { 1.137 + _inner_classes->ushort_at_put( 1.138 + _idx + instanceKlass::inner_class_inner_name_offset, index); 1.139 + } 1.140 + 1.141 + u2 inner_access_flags() const { 1.142 + return _inner_classes->ushort_at( 1.143 + _idx + instanceKlass::inner_class_access_flags_offset); 1.144 + } 1.145 +}; 1.146 + 1.147 #endif // SHARE_VM_OOPS_INSTANCEKLASS_HPP