112 |
113 |
113 #endif // ndef DTRACE_ENABLED |
114 #endif // ndef DTRACE_ENABLED |
114 |
115 |
115 volatile int InstanceKlass::_total_instanceKlass_count = 0; |
116 volatile int InstanceKlass::_total_instanceKlass_count = 0; |
116 |
117 |
117 InstanceKlass* InstanceKlass::allocate_instance_klass( |
118 static inline bool is_class_loader(const Symbol* class_name, |
118 ClassLoaderData* loader_data, |
119 const ClassFileParser& parser) { |
119 int vtable_len, |
120 assert(class_name != NULL, "invariant"); |
120 int itable_len, |
121 |
121 int static_field_size, |
122 if (class_name == vmSymbols::java_lang_ClassLoader()) { |
122 int nonstatic_oop_map_size, |
123 return true; |
123 ReferenceType rt, |
124 } |
124 AccessFlags access_flags, |
125 |
125 Symbol* name, |
126 if (SystemDictionary::ClassLoader_klass_loaded()) { |
126 Klass* super_klass, |
127 const Klass* const super_klass = parser.super_klass(); |
127 bool is_anonymous, |
128 if (super_klass != NULL) { |
128 TRAPS) { |
129 if (super_klass->is_subtype_of(SystemDictionary::ClassLoader_klass())) { |
129 |
130 return true; |
130 int size = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size, |
131 } |
131 access_flags.is_interface(), is_anonymous); |
132 } |
|
133 } |
|
134 return false; |
|
135 } |
|
136 |
|
137 InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) { |
|
138 const int size = InstanceKlass::size(parser.vtable_size(), |
|
139 parser.itable_size(), |
|
140 nonstatic_oop_map_size(parser.total_oop_map_count()), |
|
141 parser.is_interface(), |
|
142 parser.is_anonymous()); |
|
143 |
|
144 const Symbol* const class_name = parser.class_name(); |
|
145 assert(class_name != NULL, "invariant"); |
|
146 ClassLoaderData* loader_data = parser.loader_data(); |
|
147 assert(loader_data != NULL, "invariant"); |
|
148 |
|
149 InstanceKlass* ik; |
132 |
150 |
133 // Allocation |
151 // Allocation |
134 InstanceKlass* ik; |
152 if (REF_NONE == parser.reference_type()) { |
135 if (rt == REF_NONE) { |
153 if (class_name == vmSymbols::java_lang_Class()) { |
136 if (name == vmSymbols::java_lang_Class()) { |
154 // mirror |
137 ik = new (loader_data, size, THREAD) InstanceMirrorKlass( |
155 ik = new (loader_data, size, THREAD) InstanceMirrorKlass(parser); |
138 vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt, |
156 } |
139 access_flags, is_anonymous); |
157 else if (is_class_loader(class_name, parser)) { |
140 } else if (name == vmSymbols::java_lang_ClassLoader() || |
158 // class loader |
141 (SystemDictionary::ClassLoader_klass_loaded() && |
159 ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass(parser); |
142 super_klass != NULL && |
160 } |
143 super_klass->is_subtype_of(SystemDictionary::ClassLoader_klass()))) { |
161 else { |
144 ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass( |
162 // normal |
145 vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt, |
163 ik = new (loader_data, size, THREAD) InstanceKlass(parser, InstanceKlass::_misc_kind_other); |
146 access_flags, is_anonymous); |
164 } |
147 } else { |
165 } |
148 // normal class |
166 else { |
149 ik = new (loader_data, size, THREAD) InstanceKlass( |
167 // reference |
150 vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, |
168 ik = new (loader_data, size, THREAD) InstanceRefKlass(parser); |
151 InstanceKlass::_misc_kind_other, rt, access_flags, is_anonymous); |
|
152 } |
|
153 } else { |
|
154 // reference klass |
|
155 ik = new (loader_data, size, THREAD) InstanceRefKlass( |
|
156 vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt, |
|
157 access_flags, is_anonymous); |
|
158 } |
169 } |
159 |
170 |
160 // Check for pending exception before adding to the loader data and incrementing |
171 // Check for pending exception before adding to the loader data and incrementing |
161 // class count. Can get OOM here. |
172 // class count. Can get OOM here. |
162 if (HAS_PENDING_EXCEPTION) { |
173 if (HAS_PENDING_EXCEPTION) { |
163 return NULL; |
174 return NULL; |
164 } |
175 } |
165 |
176 |
|
177 assert(ik != NULL, "invariant"); |
|
178 |
|
179 const bool publicize = !parser.is_internal(); |
|
180 |
166 // Add all classes to our internal class loader list here, |
181 // Add all classes to our internal class loader list here, |
167 // including classes in the bootstrap (NULL) class loader. |
182 // including classes in the bootstrap (NULL) class loader. |
168 loader_data->add_class(ik); |
183 loader_data->add_class(ik, publicize); |
169 |
|
170 Atomic::inc(&_total_instanceKlass_count); |
184 Atomic::inc(&_total_instanceKlass_count); |
|
185 |
171 return ik; |
186 return ik; |
172 } |
187 } |
173 |
188 |
174 |
189 |
175 // copy method ordering from resource area to Metaspace |
190 // copy method ordering from resource area to Metaspace |
176 void InstanceKlass::copy_method_ordering(intArray* m, TRAPS) { |
191 void InstanceKlass::copy_method_ordering(const intArray* m, TRAPS) { |
177 if (m != NULL) { |
192 if (m != NULL) { |
178 // allocate a new array and copy contents (memcpy?) |
193 // allocate a new array and copy contents (memcpy?) |
179 _method_ordering = MetadataFactory::new_array<int>(class_loader_data(), m->length(), CHECK); |
194 _method_ordering = MetadataFactory::new_array<int>(class_loader_data(), m->length(), CHECK); |
180 for (int i = 0; i < m->length(); i++) { |
195 for (int i = 0; i < m->length(); i++) { |
181 _method_ordering->at_put(i, m->at(i)); |
196 _method_ordering->at_put(i, m->at(i)); |
191 assert(default_vtable_indices() == NULL, "only create once"); |
206 assert(default_vtable_indices() == NULL, "only create once"); |
192 set_default_vtable_indices(vtable_indices); |
207 set_default_vtable_indices(vtable_indices); |
193 return vtable_indices; |
208 return vtable_indices; |
194 } |
209 } |
195 |
210 |
196 InstanceKlass::InstanceKlass(int vtable_len, |
211 InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind) : |
197 int itable_len, |
212 _static_field_size(parser.static_field_size()), |
198 int static_field_size, |
213 _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())), |
199 int nonstatic_oop_map_size, |
214 _vtable_len(parser.vtable_size()), |
200 unsigned kind, |
215 _itable_len(parser.itable_size()), |
201 ReferenceType rt, |
216 _reference_type(parser.reference_type()) { |
202 AccessFlags access_flags, |
217 set_kind(kind); |
203 bool is_anonymous) { |
218 set_access_flags(parser.access_flags()); |
204 No_Safepoint_Verifier no_safepoint; // until k becomes parsable |
219 set_is_anonymous(parser.is_anonymous()); |
205 |
220 set_layout_helper(Klass::instance_layout_helper(parser.layout_size(), |
206 int iksize = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size, |
221 false)); |
207 access_flags.is_interface(), is_anonymous); |
222 |
208 set_vtable_length(vtable_len); |
223 assert(NULL == _methods, "underlying memory not zeroed?"); |
209 set_itable_length(itable_len); |
224 assert(is_instance_klass(), "is layout incorrect?"); |
210 set_static_field_size(static_field_size); |
225 assert(size_helper() == parser.layout_size(), "incorrect size_helper?"); |
211 set_nonstatic_oop_map_size(nonstatic_oop_map_size); |
226 } |
212 set_access_flags(access_flags); |
|
213 _misc_flags = 0; // initialize to zero |
|
214 set_kind(kind); |
|
215 set_is_anonymous(is_anonymous); |
|
216 assert(size() == iksize, "wrong size for object"); |
|
217 |
|
218 set_array_klasses(NULL); |
|
219 set_methods(NULL); |
|
220 set_method_ordering(NULL); |
|
221 set_default_methods(NULL); |
|
222 set_default_vtable_indices(NULL); |
|
223 set_local_interfaces(NULL); |
|
224 set_transitive_interfaces(NULL); |
|
225 init_implementor(); |
|
226 set_fields(NULL, 0); |
|
227 set_constants(NULL); |
|
228 set_class_loader_data(NULL); |
|
229 set_source_file_name_index(0); |
|
230 set_source_debug_extension(NULL, 0); |
|
231 set_array_name(NULL); |
|
232 set_inner_classes(NULL); |
|
233 set_static_oop_field_count(0); |
|
234 set_nonstatic_field_size(0); |
|
235 set_is_marked_dependent(false); |
|
236 _dep_context = DependencyContext::EMPTY; |
|
237 set_init_state(InstanceKlass::allocated); |
|
238 set_init_thread(NULL); |
|
239 set_reference_type(rt); |
|
240 set_oop_map_cache(NULL); |
|
241 set_jni_ids(NULL); |
|
242 set_osr_nmethods_head(NULL); |
|
243 set_breakpoints(NULL); |
|
244 init_previous_versions(); |
|
245 set_generic_signature_index(0); |
|
246 release_set_methods_jmethod_ids(NULL); |
|
247 set_annotations(NULL); |
|
248 set_jvmti_cached_class_field_map(NULL); |
|
249 set_initial_method_idnum(0); |
|
250 set_jvmti_cached_class_field_map(NULL); |
|
251 set_cached_class_file(NULL); |
|
252 set_initial_method_idnum(0); |
|
253 set_minor_version(0); |
|
254 set_major_version(0); |
|
255 NOT_PRODUCT(_verify_count = 0;) |
|
256 |
|
257 // initialize the non-header words to zero |
|
258 intptr_t* p = (intptr_t*)this; |
|
259 for (int index = InstanceKlass::header_size(); index < iksize; index++) { |
|
260 p[index] = NULL_WORD; |
|
261 } |
|
262 |
|
263 // Set temporary value until parseClassFile updates it with the real instance |
|
264 // size. |
|
265 set_layout_helper(Klass::instance_layout_helper(0, true)); |
|
266 } |
|
267 |
|
268 |
227 |
269 void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data, |
228 void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data, |
270 Array<Method*>* methods) { |
229 Array<Method*>* methods) { |
271 if (methods != NULL && methods != Universe::the_empty_method_array() && |
230 if (methods != NULL && methods != Universe::the_empty_method_array() && |
272 !methods->is_shared()) { |
231 !methods->is_shared()) { |
1382 } |
1343 } |
1383 return -1; |
1344 return -1; |
1384 } |
1345 } |
1385 |
1346 |
1386 // find_method looks up the name/signature in the local methods array |
1347 // find_method looks up the name/signature in the local methods array |
1387 Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const { |
1348 Method* InstanceKlass::find_method(const Symbol* name, |
|
1349 const Symbol* signature) const { |
1388 return find_method_impl(name, signature, find_overpass, find_static, find_private); |
1350 return find_method_impl(name, signature, find_overpass, find_static, find_private); |
1389 } |
1351 } |
1390 |
1352 |
1391 Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, |
1353 Method* InstanceKlass::find_method_impl(const Symbol* name, |
|
1354 const Symbol* signature, |
1392 OverpassLookupMode overpass_mode, |
1355 OverpassLookupMode overpass_mode, |
1393 StaticLookupMode static_mode, |
1356 StaticLookupMode static_mode, |
1394 PrivateLookupMode private_mode) const { |
1357 PrivateLookupMode private_mode) const { |
1395 return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode); |
1358 return InstanceKlass::find_method_impl(methods(), |
|
1359 name, |
|
1360 signature, |
|
1361 overpass_mode, |
|
1362 static_mode, |
|
1363 private_mode); |
1396 } |
1364 } |
1397 |
1365 |
1398 // find_instance_method looks up the name/signature in the local methods array |
1366 // find_instance_method looks up the name/signature in the local methods array |
1399 // and skips over static methods |
1367 // and skips over static methods |
1400 Method* InstanceKlass::find_instance_method( |
1368 Method* InstanceKlass::find_instance_method(const Array<Method*>* methods, |
1401 Array<Method*>* methods, Symbol* name, Symbol* signature) { |
1369 const Symbol* name, |
1402 Method* meth = InstanceKlass::find_method_impl(methods, name, signature, |
1370 const Symbol* signature) { |
1403 find_overpass, skip_static, find_private); |
1371 Method* const meth = InstanceKlass::find_method_impl(methods, |
1404 assert(((meth == NULL) || !meth->is_static()), "find_instance_method should have skipped statics"); |
1372 name, |
|
1373 signature, |
|
1374 find_overpass, |
|
1375 skip_static, |
|
1376 find_private); |
|
1377 assert(((meth == NULL) || !meth->is_static()), |
|
1378 "find_instance_method should have skipped statics"); |
1405 return meth; |
1379 return meth; |
1406 } |
1380 } |
1407 |
1381 |
1408 // find_instance_method looks up the name/signature in the local methods array |
1382 // find_instance_method looks up the name/signature in the local methods array |
1409 // and skips over static methods |
1383 // and skips over static methods |
1410 Method* InstanceKlass::find_instance_method(Symbol* name, Symbol* signature) { |
1384 Method* InstanceKlass::find_instance_method(const Symbol* name, const Symbol* signature) const { |
1411 return InstanceKlass::find_instance_method(methods(), name, signature); |
1385 return InstanceKlass::find_instance_method(methods(), name, signature); |
1412 } |
1386 } |
1413 |
1387 |
1414 // Find looks up the name/signature in the local methods array |
1388 // Find looks up the name/signature in the local methods array |
1415 // and filters on the overpass, static and private flags |
1389 // and filters on the overpass, static and private flags |
1416 // This returns the first one found |
1390 // This returns the first one found |
1417 // note that the local methods array can have up to one overpass, one static |
1391 // note that the local methods array can have up to one overpass, one static |
1418 // and one instance (private or not) with the same name/signature |
1392 // and one instance (private or not) with the same name/signature |
1419 Method* InstanceKlass::find_local_method(Symbol* name, Symbol* signature, |
1393 Method* InstanceKlass::find_local_method(const Symbol* name, |
1420 OverpassLookupMode overpass_mode, |
1394 const Symbol* signature, |
1421 StaticLookupMode static_mode, |
1395 OverpassLookupMode overpass_mode, |
1422 PrivateLookupMode private_mode) const { |
1396 StaticLookupMode static_mode, |
1423 return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode); |
1397 PrivateLookupMode private_mode) const { |
|
1398 return InstanceKlass::find_method_impl(methods(), |
|
1399 name, |
|
1400 signature, |
|
1401 overpass_mode, |
|
1402 static_mode, |
|
1403 private_mode); |
1424 } |
1404 } |
1425 |
1405 |
1426 // Find looks up the name/signature in the local methods array |
1406 // Find looks up the name/signature in the local methods array |
1427 // and filters on the overpass, static and private flags |
1407 // and filters on the overpass, static and private flags |
1428 // This returns the first one found |
1408 // This returns the first one found |
1429 // note that the local methods array can have up to one overpass, one static |
1409 // note that the local methods array can have up to one overpass, one static |
1430 // and one instance (private or not) with the same name/signature |
1410 // and one instance (private or not) with the same name/signature |
1431 Method* InstanceKlass::find_local_method(Array<Method*>* methods, |
1411 Method* InstanceKlass::find_local_method(const Array<Method*>* methods, |
1432 Symbol* name, Symbol* signature, |
1412 const Symbol* name, |
|
1413 const Symbol* signature, |
|
1414 OverpassLookupMode overpass_mode, |
|
1415 StaticLookupMode static_mode, |
|
1416 PrivateLookupMode private_mode) { |
|
1417 return InstanceKlass::find_method_impl(methods, |
|
1418 name, |
|
1419 signature, |
|
1420 overpass_mode, |
|
1421 static_mode, |
|
1422 private_mode); |
|
1423 } |
|
1424 |
|
1425 Method* InstanceKlass::find_method(const Array<Method*>* methods, |
|
1426 const Symbol* name, |
|
1427 const Symbol* signature) { |
|
1428 return InstanceKlass::find_method_impl(methods, |
|
1429 name, |
|
1430 signature, |
|
1431 find_overpass, |
|
1432 find_static, |
|
1433 find_private); |
|
1434 } |
|
1435 |
|
1436 Method* InstanceKlass::find_method_impl(const Array<Method*>* methods, |
|
1437 const Symbol* name, |
|
1438 const Symbol* signature, |
1433 OverpassLookupMode overpass_mode, |
1439 OverpassLookupMode overpass_mode, |
1434 StaticLookupMode static_mode, |
1440 StaticLookupMode static_mode, |
1435 PrivateLookupMode private_mode) { |
1441 PrivateLookupMode private_mode) { |
1436 return InstanceKlass::find_method_impl(methods, name, signature, overpass_mode, static_mode, private_mode); |
|
1437 } |
|
1438 |
|
1439 |
|
1440 // find_method looks up the name/signature in the local methods array |
|
1441 Method* InstanceKlass::find_method( |
|
1442 Array<Method*>* methods, Symbol* name, Symbol* signature) { |
|
1443 return InstanceKlass::find_method_impl(methods, name, signature, find_overpass, find_static, find_private); |
|
1444 } |
|
1445 |
|
1446 Method* InstanceKlass::find_method_impl( |
|
1447 Array<Method*>* methods, Symbol* name, Symbol* signature, |
|
1448 OverpassLookupMode overpass_mode, StaticLookupMode static_mode, |
|
1449 PrivateLookupMode private_mode) { |
|
1450 int hit = find_method_index(methods, name, signature, overpass_mode, static_mode, private_mode); |
1442 int hit = find_method_index(methods, name, signature, overpass_mode, static_mode, private_mode); |
1451 return hit >= 0 ? methods->at(hit): NULL; |
1443 return hit >= 0 ? methods->at(hit): NULL; |
1452 } |
1444 } |
1453 |
1445 |
1454 bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static, bool skipping_private) { |
1446 // true if method matches signature and conforms to skipping_X conditions. |
1455 return ((m->signature() == signature) && |
1447 static bool method_matches(const Method* m, |
1456 (!skipping_overpass || !m->is_overpass()) && |
1448 const Symbol* signature, |
1457 (!skipping_static || !m->is_static()) && |
1449 bool skipping_overpass, |
1458 (!skipping_private || !m->is_private())); |
1450 bool skipping_static, |
|
1451 bool skipping_private) { |
|
1452 return ((m->signature() == signature) && |
|
1453 (!skipping_overpass || !m->is_overpass()) && |
|
1454 (!skipping_static || !m->is_static()) && |
|
1455 (!skipping_private || !m->is_private())); |
1459 } |
1456 } |
1460 |
1457 |
1461 // Used directly for default_methods to find the index into the |
1458 // Used directly for default_methods to find the index into the |
1462 // default_vtable_indices, and indirectly by find_method |
1459 // default_vtable_indices, and indirectly by find_method |
1463 // find_method_index looks in the local methods array to return the index |
1460 // find_method_index looks in the local methods array to return the index |
1468 // There is the possibility in any _method's array to have the same name/signature |
1465 // There is the possibility in any _method's array to have the same name/signature |
1469 // for a static method, an overpass method and a local instance method |
1466 // for a static method, an overpass method and a local instance method |
1470 // To correctly catch a given method, the search criteria may need |
1467 // To correctly catch a given method, the search criteria may need |
1471 // to explicitly skip the other two. For local instance methods, it |
1468 // to explicitly skip the other two. For local instance methods, it |
1472 // is often necessary to skip private methods |
1469 // is often necessary to skip private methods |
1473 int InstanceKlass::find_method_index( |
1470 int InstanceKlass::find_method_index(const Array<Method*>* methods, |
1474 Array<Method*>* methods, Symbol* name, Symbol* signature, |
1471 const Symbol* name, |
1475 OverpassLookupMode overpass_mode, StaticLookupMode static_mode, |
1472 const Symbol* signature, |
1476 PrivateLookupMode private_mode) { |
1473 OverpassLookupMode overpass_mode, |
1477 bool skipping_overpass = (overpass_mode == skip_overpass); |
1474 StaticLookupMode static_mode, |
1478 bool skipping_static = (static_mode == skip_static); |
1475 PrivateLookupMode private_mode) { |
1479 bool skipping_private = (private_mode == skip_private); |
1476 const bool skipping_overpass = (overpass_mode == skip_overpass); |
1480 int hit = binary_search(methods, name); |
1477 const bool skipping_static = (static_mode == skip_static); |
|
1478 const bool skipping_private = (private_mode == skip_private); |
|
1479 const int hit = binary_search(methods, name); |
1481 if (hit != -1) { |
1480 if (hit != -1) { |
1482 Method* m = methods->at(hit); |
1481 const Method* const m = methods->at(hit); |
1483 |
1482 |
1484 // Do linear search to find matching signature. First, quick check |
1483 // Do linear search to find matching signature. First, quick check |
1485 // for common case, ignoring overpasses if requested. |
1484 // for common case, ignoring overpasses if requested. |
1486 if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return hit; |
1485 if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) { |
|
1486 return hit; |
|
1487 } |
1487 |
1488 |
1488 // search downwards through overloaded methods |
1489 // search downwards through overloaded methods |
1489 int i; |
1490 int i; |
1490 for (i = hit - 1; i >= 0; --i) { |
1491 for (i = hit - 1; i >= 0; --i) { |
1491 Method* m = methods->at(i); |
1492 const Method* const m = methods->at(i); |
1492 assert(m->is_method(), "must be method"); |
1493 assert(m->is_method(), "must be method"); |
1493 if (m->name() != name) break; |
1494 if (m->name() != name) { |
1494 if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i; |
1495 break; |
|
1496 } |
|
1497 if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) { |
|
1498 return i; |
|
1499 } |
1495 } |
1500 } |
1496 // search upwards |
1501 // search upwards |
1497 for (i = hit + 1; i < methods->length(); ++i) { |
1502 for (i = hit + 1; i < methods->length(); ++i) { |
1498 Method* m = methods->at(i); |
1503 const Method* const m = methods->at(i); |
1499 assert(m->is_method(), "must be method"); |
1504 assert(m->is_method(), "must be method"); |
1500 if (m->name() != name) break; |
1505 if (m->name() != name) { |
1501 if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i; |
1506 break; |
|
1507 } |
|
1508 if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) { |
|
1509 return i; |
|
1510 } |
1502 } |
1511 } |
1503 // not found |
1512 // not found |
1504 #ifdef ASSERT |
1513 #ifdef ASSERT |
1505 int index = (skipping_overpass || skipping_static || skipping_private) ? -1 : linear_search(methods, name, signature); |
1514 const int index = (skipping_overpass || skipping_static || skipping_private) ? -1 : |
1506 assert(index == -1, "binary search should have found entry %d", index); |
1515 linear_search(methods, name, signature); |
|
1516 assert(-1 == index, "binary search should have found entry %d", index); |
1507 #endif |
1517 #endif |
1508 } |
1518 } |
1509 return -1; |
1519 return -1; |
1510 } |
1520 } |
1511 int InstanceKlass::find_method_by_name(Symbol* name, int* end) { |
1521 |
|
1522 int InstanceKlass::find_method_by_name(const Symbol* name, int* end) const { |
1512 return find_method_by_name(methods(), name, end); |
1523 return find_method_by_name(methods(), name, end); |
1513 } |
1524 } |
1514 |
1525 |
1515 int InstanceKlass::find_method_by_name( |
1526 int InstanceKlass::find_method_by_name(const Array<Method*>* methods, |
1516 Array<Method*>* methods, Symbol* name, int* end_ptr) { |
1527 const Symbol* name, |
|
1528 int* end_ptr) { |
1517 assert(end_ptr != NULL, "just checking"); |
1529 assert(end_ptr != NULL, "just checking"); |
1518 int start = binary_search(methods, name); |
1530 int start = binary_search(methods, name); |
1519 int end = start + 1; |
1531 int end = start + 1; |
1520 if (start != -1) { |
1532 if (start != -1) { |
1521 while (start - 1 >= 0 && (methods->at(start - 1))->name() == name) --start; |
1533 while (start - 1 >= 0 && (methods->at(start - 1))->name() == name) --start; |
2162 dest[dest_index] = '\0'; |
2179 dest[dest_index] = '\0'; |
2163 return dest; |
2180 return dest; |
2164 } |
2181 } |
2165 |
2182 |
2166 // different verisons of is_same_class_package |
2183 // different verisons of is_same_class_package |
2167 bool InstanceKlass::is_same_class_package(Klass* class2) { |
2184 bool InstanceKlass::is_same_class_package(const Klass* class2) const { |
|
2185 const Klass* const class1 = (const Klass* const)this; |
|
2186 oop classloader1 = InstanceKlass::cast(class1)->class_loader(); |
|
2187 const Symbol* const classname1 = class1->name(); |
|
2188 |
2168 if (class2->is_objArray_klass()) { |
2189 if (class2->is_objArray_klass()) { |
2169 class2 = ObjArrayKlass::cast(class2)->bottom_klass(); |
2190 class2 = ObjArrayKlass::cast(class2)->bottom_klass(); |
2170 } |
2191 } |
2171 oop classloader2 = class2->class_loader(); |
2192 oop classloader2; |
2172 Symbol* classname2 = class2->name(); |
2193 if (class2->is_instance_klass()) { |
2173 |
2194 classloader2 = InstanceKlass::cast(class2)->class_loader(); |
2174 return InstanceKlass::is_same_class_package(class_loader(), name(), |
2195 } else { |
|
2196 assert(class2->is_typeArray_klass(), "should be type array"); |
|
2197 classloader2 = NULL; |
|
2198 } |
|
2199 const Symbol* classname2 = class2->name(); |
|
2200 |
|
2201 return InstanceKlass::is_same_class_package(classloader1, classname1, |
2175 classloader2, classname2); |
2202 classloader2, classname2); |
2176 } |
2203 } |
2177 |
2204 |
2178 bool InstanceKlass::is_same_class_package(oop classloader2, Symbol* classname2) { |
2205 bool InstanceKlass::is_same_class_package(oop other_class_loader, |
2179 return InstanceKlass::is_same_class_package(class_loader(), name(), |
2206 const Symbol* other_class_name) const { |
2180 classloader2, classname2); |
2207 oop this_class_loader = class_loader(); |
|
2208 const Symbol* const this_class_name = name(); |
|
2209 |
|
2210 return InstanceKlass::is_same_class_package(this_class_loader, |
|
2211 this_class_name, |
|
2212 other_class_loader, |
|
2213 other_class_name); |
2181 } |
2214 } |
2182 |
2215 |
2183 // return true if two classes are in the same package, classloader |
2216 // return true if two classes are in the same package, classloader |
2184 // and classname information is enough to determine a class's package |
2217 // and classname information is enough to determine a class's package |
2185 bool InstanceKlass::is_same_class_package(oop class_loader1, Symbol* class_name1, |
2218 bool InstanceKlass::is_same_class_package(oop class_loader1, const Symbol* class_name1, |
2186 oop class_loader2, Symbol* class_name2) { |
2219 oop class_loader2, const Symbol* class_name2) { |
2187 if (class_loader1 != class_loader2) { |
2220 if (class_loader1 != class_loader2) { |
2188 return false; |
2221 return false; |
2189 } else if (class_name1 == class_name2) { |
2222 } else if (class_name1 == class_name2) { |
2190 return true; // skip painful bytewise comparison |
2223 return true; // skip painful bytewise comparison |
2191 } else { |
2224 } else { |
2260 ... |
2293 ... |
2261 } |
2294 } |
2262 */ |
2295 */ |
2263 |
2296 |
2264 // tell if two classes have the same enclosing class (at package level) |
2297 // tell if two classes have the same enclosing class (at package level) |
2265 bool InstanceKlass::is_same_package_member_impl(instanceKlassHandle class1, |
2298 bool InstanceKlass::is_same_package_member_impl(const InstanceKlass* class1, |
2266 Klass* class2_oop, TRAPS) { |
2299 const Klass* class2, |
2267 if (class2_oop == class1()) return true; |
2300 TRAPS) { |
2268 if (!class2_oop->is_instance_klass()) return false; |
2301 if (class2 == class1) return true; |
2269 instanceKlassHandle class2(THREAD, class2_oop); |
2302 if (!class2->is_instance_klass()) return false; |
2270 |
2303 |
2271 // must be in same package before we try anything else |
2304 // must be in same package before we try anything else |
2272 if (!class1->is_same_class_package(class2->class_loader(), class2->name())) |
2305 if (!class1->is_same_class_package(class2->class_loader(), class2->name())) |
2273 return false; |
2306 return false; |
2274 |
2307 |
2275 // As long as there is an outer1.getEnclosingClass, |
2308 // As long as there is an outer1.getEnclosingClass, |
2276 // shift the search outward. |
2309 // shift the search outward. |
2277 instanceKlassHandle outer1 = class1; |
2310 const InstanceKlass* outer1 = class1; |
2278 for (;;) { |
2311 for (;;) { |
2279 // As we walk along, look for equalities between outer1 and class2. |
2312 // As we walk along, look for equalities between outer1 and class2. |
2280 // Eventually, the walks will terminate as outer1 stops |
2313 // Eventually, the walks will terminate as outer1 stops |
2281 // at the top-level class around the original class. |
2314 // at the top-level class around the original class. |
2282 bool ignore_inner_is_member; |
2315 bool ignore_inner_is_member; |
2283 Klass* next = outer1->compute_enclosing_class(&ignore_inner_is_member, |
2316 const Klass* next = outer1->compute_enclosing_class(&ignore_inner_is_member, |
2284 CHECK_false); |
2317 CHECK_false); |
2285 if (next == NULL) break; |
2318 if (next == NULL) break; |
2286 if (next == class2()) return true; |
2319 if (next == class2) return true; |
2287 outer1 = instanceKlassHandle(THREAD, next); |
2320 outer1 = InstanceKlass::cast(next); |
2288 } |
2321 } |
2289 |
2322 |
2290 // Now do the same for class2. |
2323 // Now do the same for class2. |
2291 instanceKlassHandle outer2 = class2; |
2324 const InstanceKlass* outer2 = InstanceKlass::cast(class2); |
2292 for (;;) { |
2325 for (;;) { |
2293 bool ignore_inner_is_member; |
2326 bool ignore_inner_is_member; |
2294 Klass* next = outer2->compute_enclosing_class(&ignore_inner_is_member, |
2327 Klass* next = outer2->compute_enclosing_class(&ignore_inner_is_member, |
2295 CHECK_false); |
2328 CHECK_false); |
2296 if (next == NULL) break; |
2329 if (next == NULL) break; |
2297 // Might as well check the new outer against all available values. |
2330 // Might as well check the new outer against all available values. |
2298 if (next == class1()) return true; |
2331 if (next == class1) return true; |
2299 if (next == outer1()) return true; |
2332 if (next == outer1) return true; |
2300 outer2 = instanceKlassHandle(THREAD, next); |
2333 outer2 = InstanceKlass::cast(next); |
2301 } |
2334 } |
2302 |
2335 |
2303 // If by this point we have not found an equality between the |
2336 // If by this point we have not found an equality between the |
2304 // two classes, we know they are in separate package members. |
2337 // two classes, we know they are in separate package members. |
2305 return false; |
2338 return false; |
2323 } |
2356 } |
2324 } |
2357 } |
2325 return false; |
2358 return false; |
2326 } |
2359 } |
2327 |
2360 |
2328 Klass* InstanceKlass::compute_enclosing_class_impl(instanceKlassHandle k, bool* inner_is_member, TRAPS) { |
2361 InstanceKlass* InstanceKlass::compute_enclosing_class_impl(const InstanceKlass* k, |
2329 instanceKlassHandle outer_klass; |
2362 bool* inner_is_member, |
|
2363 TRAPS) { |
|
2364 InstanceKlass* outer_klass = NULL; |
2330 *inner_is_member = false; |
2365 *inner_is_member = false; |
2331 int ooff = 0, noff = 0; |
2366 int ooff = 0, noff = 0; |
2332 if (find_inner_classes_attr(k, &ooff, &noff, THREAD)) { |
2367 if (find_inner_classes_attr(k, &ooff, &noff, THREAD)) { |
2333 constantPoolHandle i_cp(THREAD, k->constants()); |
2368 constantPoolHandle i_cp(THREAD, k->constants()); |
2334 if (ooff != 0) { |
2369 if (ooff != 0) { |
2335 Klass* ok = i_cp->klass_at(ooff, CHECK_NULL); |
2370 Klass* ok = i_cp->klass_at(ooff, CHECK_NULL); |
2336 outer_klass = instanceKlassHandle(THREAD, ok); |
2371 outer_klass = InstanceKlass::cast(ok); |
2337 *inner_is_member = true; |
2372 *inner_is_member = true; |
2338 } |
2373 } |
2339 if (outer_klass.is_null()) { |
2374 if (NULL == outer_klass) { |
2340 // It may be anonymous; try for that. |
2375 // It may be anonymous; try for that. |
2341 int encl_method_class_idx = k->enclosing_method_class_index(); |
2376 int encl_method_class_idx = k->enclosing_method_class_index(); |
2342 if (encl_method_class_idx != 0) { |
2377 if (encl_method_class_idx != 0) { |
2343 Klass* ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL); |
2378 Klass* ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL); |
2344 outer_klass = instanceKlassHandle(THREAD, ok); |
2379 outer_klass = InstanceKlass::cast(ok); |
2345 *inner_is_member = false; |
2380 *inner_is_member = false; |
2346 } |
2381 } |
2347 } |
2382 } |
2348 } |
2383 } |
2349 |
2384 |
2350 // If no inner class attribute found for this class. |
2385 // If no inner class attribute found for this class. |
2351 if (outer_klass.is_null()) return NULL; |
2386 if (NULL == outer_klass) return NULL; |
2352 |
2387 |
2353 // Throws an exception if outer klass has not declared k as an inner klass |
2388 // Throws an exception if outer klass has not declared k as an inner klass |
2354 // We need evidence that each klass knows about the other, or else |
2389 // We need evidence that each klass knows about the other, or else |
2355 // the system could allow a spoof of an inner class to gain access rights. |
2390 // the system could allow a spoof of an inner class to gain access rights. |
2356 Reflection::check_for_inner_class(outer_klass, k, *inner_is_member, CHECK_NULL); |
2391 Reflection::check_for_inner_class(outer_klass, k, *inner_is_member, CHECK_NULL); |
2357 return outer_klass(); |
2392 return outer_klass; |
2358 } |
2393 } |
2359 |
2394 |
2360 jint InstanceKlass::compute_modifier_flags(TRAPS) const { |
2395 jint InstanceKlass::compute_modifier_flags(TRAPS) const { |
2361 jint access = access_flags().as_int(); |
2396 jint access = access_flags().as_int(); |
2362 |
2397 |