1 /* |
1 /* |
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
37 // A KlassStream is an abstract stream for streaming over self, superclasses |
37 // A KlassStream is an abstract stream for streaming over self, superclasses |
38 // and (super)interfaces. Streaming is done in reverse order (subclasses first, |
38 // and (super)interfaces. Streaming is done in reverse order (subclasses first, |
39 // interfaces last). |
39 // interfaces last). |
40 // |
40 // |
41 // for (KlassStream st(k, false, false); !st.eos(); st.next()) { |
41 // for (KlassStream st(k, false, false); !st.eos(); st.next()) { |
42 // klassOop k = st.klass(); |
42 // Klass* k = st.klass(); |
43 // ... |
43 // ... |
44 // } |
44 // } |
45 |
45 |
46 class KlassStream VALUE_OBJ_CLASS_SPEC { |
46 class KlassStream VALUE_OBJ_CLASS_SPEC { |
47 protected: |
47 protected: |
48 instanceKlassHandle _klass; // current klass/interface iterated over |
48 instanceKlassHandle _klass; // current klass/interface iterated over |
49 objArrayHandle _interfaces; // transitive interfaces for initial class |
49 Array<Klass*>* _interfaces; // transitive interfaces for initial class |
50 int _interface_index; // current interface being processed |
50 int _interface_index; // current interface being processed |
51 bool _local_only; // process initial class/interface only |
51 bool _local_only; // process initial class/interface only |
52 bool _classes_only; // process classes only (no interfaces) |
52 bool _classes_only; // process classes only (no interfaces) |
53 int _index; |
53 int _index; |
54 |
54 |
73 // A MethodStream streams over all methods in a class, superclasses and (super)interfaces. |
73 // A MethodStream streams over all methods in a class, superclasses and (super)interfaces. |
74 // Streaming is done in reverse order (subclasses first, methods in reverse order) |
74 // Streaming is done in reverse order (subclasses first, methods in reverse order) |
75 // Usage: |
75 // Usage: |
76 // |
76 // |
77 // for (MethodStream st(k, false, false); !st.eos(); st.next()) { |
77 // for (MethodStream st(k, false, false); !st.eos(); st.next()) { |
78 // methodOop m = st.method(); |
78 // Method* m = st.method(); |
79 // ... |
79 // ... |
80 // } |
80 // } |
81 |
81 |
82 class MethodStream : public KlassStream { |
82 class MethodStream : public KlassStream { |
83 private: |
83 private: |
84 int length() const { return methods()->length(); } |
84 int length() const { return methods()->length(); } |
85 objArrayOop methods() const { return _klass->methods(); } |
85 Array<Method*>* methods() const { return _klass->methods(); } |
86 public: |
86 public: |
87 MethodStream(instanceKlassHandle klass, bool local_only, bool classes_only) |
87 MethodStream(instanceKlassHandle klass, bool local_only, bool classes_only) |
88 : KlassStream(klass, local_only, classes_only) { |
88 : KlassStream(klass, local_only, classes_only) { |
89 _index = length(); |
89 _index = length(); |
90 next(); |
90 next(); |
91 } |
91 } |
92 |
92 |
93 void next() { _index--; } |
93 void next() { _index--; } |
94 methodOop method() const { return methodOop(methods()->obj_at(index())); } |
94 Method* method() const { return methods()->at(index()); } |
95 }; |
95 }; |
96 |
96 |
97 |
97 |
98 // A FieldStream streams over all fields in a class, superclasses and (super)interfaces. |
98 // A FieldStream streams over all fields in a class, superclasses and (super)interfaces. |
99 // Streaming is done in reverse order (subclasses first, fields in reverse order) |
99 // Streaming is done in reverse order (subclasses first, fields in reverse order) |
136 } |
136 } |
137 }; |
137 }; |
138 |
138 |
139 class FilteredField { |
139 class FilteredField { |
140 private: |
140 private: |
141 klassOop _klass; |
141 Klass* _klass; |
142 int _field_offset; |
142 int _field_offset; |
143 |
143 |
144 public: |
144 public: |
145 FilteredField(klassOop klass, int field_offset) { |
145 FilteredField(Klass* klass, int field_offset) { |
146 _klass = klass; |
146 _klass = klass; |
147 _field_offset = field_offset; |
147 _field_offset = field_offset; |
148 } |
148 } |
149 klassOop klass() { return _klass; } |
149 Klass* klass() { return _klass; } |
150 oop* klass_addr() { return (oop*) &_klass; } |
|
151 int field_offset() { return _field_offset; } |
150 int field_offset() { return _field_offset; } |
152 }; |
151 }; |
153 |
152 |
154 class FilteredFieldsMap : AllStatic { |
153 class FilteredFieldsMap : AllStatic { |
155 private: |
154 private: |
156 static GrowableArray<FilteredField *> *_filtered_fields; |
155 static GrowableArray<FilteredField *> *_filtered_fields; |
157 public: |
156 public: |
158 static void initialize(); |
157 static void initialize(); |
159 static bool is_filtered_field(klassOop klass, int field_offset) { |
158 static bool is_filtered_field(Klass* klass, int field_offset) { |
160 for (int i=0; i < _filtered_fields->length(); i++) { |
159 for (int i=0; i < _filtered_fields->length(); i++) { |
161 if (klass == _filtered_fields->at(i)->klass() && |
160 if (klass == _filtered_fields->at(i)->klass() && |
162 field_offset == _filtered_fields->at(i)->field_offset()) { |
161 field_offset == _filtered_fields->at(i)->field_offset()) { |
163 return true; |
162 return true; |
164 } |
163 } |
165 } |
164 } |
166 return false; |
165 return false; |
167 } |
166 } |
168 static int filtered_fields_count(klassOop klass, bool local_only) { |
167 static int filtered_fields_count(Klass* klass, bool local_only) { |
169 int nflds = 0; |
168 int nflds = 0; |
170 for (int i=0; i < _filtered_fields->length(); i++) { |
169 for (int i=0; i < _filtered_fields->length(); i++) { |
171 if (local_only && klass == _filtered_fields->at(i)->klass()) { |
170 if (local_only && klass == _filtered_fields->at(i)->klass()) { |
172 nflds++; |
171 nflds++; |
173 } else if (klass->klass_part()->is_subtype_of(_filtered_fields->at(i)->klass())) { |
172 } else if (klass->is_subtype_of(_filtered_fields->at(i)->klass())) { |
174 nflds++; |
173 nflds++; |
175 } |
174 } |
176 } |
175 } |
177 return nflds; |
176 return nflds; |
178 } |
177 } |
179 // GC support. |
178 // Enhance Class Redefinition Support |
180 static void klasses_oops_do(OopClosure* f) { |
179 static void classes_do(KlassClosure* f) { |
181 for (int i = 0; i < _filtered_fields->length(); i++) { |
180 for (int i = 0; i < _filtered_fields->length(); i++) { |
182 f->do_oop((oop*)_filtered_fields->at(i)->klass_addr()); |
181 f->do_klass(_filtered_fields->at(i)->klass()); |
183 } |
182 } |
184 } |
183 } |
185 }; |
184 }; |
186 |
185 |
187 |
186 |
202 bool has_filtered_field() { return (_filtered_fields_count > 0); } |
201 bool has_filtered_field() { return (_filtered_fields_count > 0); } |
203 |
202 |
204 public: |
203 public: |
205 FilteredFieldStream(instanceKlassHandle klass, bool local_only, bool classes_only) |
204 FilteredFieldStream(instanceKlassHandle klass, bool local_only, bool classes_only) |
206 : FieldStream(klass, local_only, classes_only) { |
205 : FieldStream(klass, local_only, classes_only) { |
207 _filtered_fields_count = FilteredFieldsMap::filtered_fields_count((klassOop)klass(), local_only); |
206 _filtered_fields_count = FilteredFieldsMap::filtered_fields_count((Klass*)klass(), local_only); |
208 } |
207 } |
209 int field_count(); |
208 int field_count(); |
210 void next() { |
209 void next() { |
211 _index -= 1; |
210 _index -= 1; |
212 if (has_filtered_field()) { |
211 if (has_filtered_field()) { |
213 while (_index >=0 && FilteredFieldsMap::is_filtered_field((klassOop)_klass(), offset())) { |
212 while (_index >=0 && FilteredFieldsMap::is_filtered_field((Klass*)_klass(), offset())) { |
214 _index -= 1; |
213 _index -= 1; |
215 } |
214 } |
216 } |
215 } |
217 } |
216 } |
218 }; |
217 }; |