changeset 50735 | 2f2af62dfac7 |
parent 50634 | c349d409262a |
child 50746 | 85789fb05154 |
50734:0828a0f6676b | 50735:2f2af62dfac7 |
---|---|
143 } |
143 } |
144 } |
144 } |
145 return false; |
145 return false; |
146 } |
146 } |
147 |
147 |
148 // called to verify that k is a member of this nest |
|
149 bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const { |
|
150 if (_nest_members == NULL || _nest_members == Universe::the_empty_short_array()) { |
|
151 if (log_is_enabled(Trace, class, nestmates)) { |
|
152 ResourceMark rm(THREAD); |
|
153 log_trace(class, nestmates)("Checked nest membership of %s in non-nest-host class %s", |
|
154 k->external_name(), this->external_name()); |
|
155 } |
|
156 return false; |
|
157 } |
|
158 |
|
159 if (log_is_enabled(Trace, class, nestmates)) { |
|
160 ResourceMark rm(THREAD); |
|
161 log_trace(class, nestmates)("Checking nest membership of %s in %s", |
|
162 k->external_name(), this->external_name()); |
|
163 } |
|
164 |
|
165 // Check names first and if they match then check actual klass. This avoids |
|
166 // resolving anything unnecessarily. |
|
167 for (int i = 0; i < _nest_members->length(); i++) { |
|
168 int cp_index = _nest_members->at(i); |
|
169 Symbol* name = _constants->klass_name_at(cp_index); |
|
170 if (name == k->name()) { |
|
171 log_trace(class, nestmates)("- Found it at nest_members[%d] => cp[%d]", i, cp_index); |
|
172 |
|
173 // names match so check actual klass - this may trigger class loading if |
|
174 // it doesn't match (but that should be impossible) |
|
175 Klass* k2 = _constants->klass_at(cp_index, CHECK_false); |
|
176 if (k2 == k) { |
|
177 log_trace(class, nestmates)("- class is listed as a nest member"); |
|
178 return true; |
|
179 } else { |
|
180 // same name but different klass! |
|
181 log_trace(class, nestmates)(" - klass comparison failed!"); |
|
182 // can't have different classes for the same name, so we're done |
|
183 return false; |
|
184 } |
|
185 } |
|
186 } |
|
187 log_trace(class, nestmates)("- class is NOT a nest member!"); |
|
188 return false; |
|
189 } |
|
190 |
|
191 // Return nest-host class, resolving, validating and saving it if needed. |
|
192 // In cases where this is called from a thread that can not do classloading |
|
193 // (such as a native JIT thread) then we simply return NULL, which in turn |
|
194 // causes the access check to return false. Such code will retry the access |
|
195 // from a more suitable environment later. |
|
196 InstanceKlass* InstanceKlass::nest_host(Symbol* validationException, TRAPS) { |
|
197 InstanceKlass* nest_host_k = _nest_host; |
|
198 if (nest_host_k == NULL) { |
|
199 // need to resolve and save our nest-host class. This could be attempted |
|
200 // concurrently but as the result is idempotent and we don't use the class |
|
201 // then we do not need any synchronization beyond what is implicitly used |
|
202 // during class loading. |
|
203 if (_nest_host_index != 0) { // we have a real nest_host |
|
204 // Before trying to resolve check if we're in a suitable context |
|
205 if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) { |
|
206 if (log_is_enabled(Trace, class, nestmates)) { |
|
207 ResourceMark rm(THREAD); |
|
208 log_trace(class, nestmates)("Rejected resolution of nest-host of %s in unsuitable thread", |
|
209 this->external_name()); |
|
210 } |
|
211 return NULL; |
|
212 } |
|
213 |
|
214 if (log_is_enabled(Trace, class, nestmates)) { |
|
215 ResourceMark rm(THREAD); |
|
216 log_trace(class, nestmates)("Resolving nest-host of %s using cp entry for %s", |
|
217 this->external_name(), |
|
218 _constants->klass_name_at(_nest_host_index)->as_C_string()); |
|
219 } |
|
220 |
|
221 Klass* k = _constants->klass_at(_nest_host_index, THREAD); |
|
222 if (HAS_PENDING_EXCEPTION) { |
|
223 Handle exc_h = Handle(THREAD, PENDING_EXCEPTION); |
|
224 if (exc_h->is_a(SystemDictionary::NoClassDefFoundError_klass())) { |
|
225 // throw a new CDNFE with the original as its cause, and a clear msg |
|
226 ResourceMark rm(THREAD); |
|
227 char buf[200]; |
|
228 CLEAR_PENDING_EXCEPTION; |
|
229 jio_snprintf(buf, sizeof(buf), |
|
230 "Unable to load nest-host class (%s) of %s", |
|
231 _constants->klass_name_at(_nest_host_index)->as_C_string(), |
|
232 this->external_name()); |
|
233 log_trace(class, nestmates)("%s - NoClassDefFoundError", buf); |
|
234 THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), buf, exc_h); |
|
235 } |
|
236 // All other exceptions pass through (OOME, StackOverflowError, LinkageErrors etc). |
|
237 return NULL; |
|
238 } |
|
239 |
|
240 // A valid nest-host is an instance class in the current package that lists this |
|
241 // class as a nest member. If any of these conditions are not met we post the |
|
242 // requested exception type (if any) and return NULL |
|
243 |
|
244 const char* error = NULL; |
|
245 |
|
246 // JVMS 5.4.4 indicates package check comes first |
|
247 if (is_same_class_package(k)) { |
|
248 |
|
249 // Now check actual membership. We can't be a member if our "host" is |
|
250 // not an instance class. |
|
251 if (k->is_instance_klass()) { |
|
252 nest_host_k = InstanceKlass::cast(k); |
|
253 |
|
254 bool is_member = nest_host_k->has_nest_member(this, CHECK_NULL); |
|
255 if (is_member) { |
|
256 // save resolved nest-host value |
|
257 _nest_host = nest_host_k; |
|
258 |
|
259 if (log_is_enabled(Trace, class, nestmates)) { |
|
260 ResourceMark rm(THREAD); |
|
261 log_trace(class, nestmates)("Resolved nest-host of %s to %s", |
|
262 this->external_name(), k->external_name()); |
|
263 } |
|
264 return nest_host_k; |
|
265 } |
|
266 } |
|
267 error = "current type is not listed as a nest member"; |
|
268 } else { |
|
269 error = "types are in different packages"; |
|
270 } |
|
271 |
|
272 if (log_is_enabled(Trace, class, nestmates)) { |
|
273 ResourceMark rm(THREAD); |
|
274 log_trace(class, nestmates)("Type %s is not a nest member of resolved type %s: %s", |
|
275 this->external_name(), |
|
276 k->external_name(), |
|
277 error); |
|
278 } |
|
279 |
|
280 if (validationException != NULL) { |
|
281 ResourceMark rm(THREAD); |
|
282 Exceptions::fthrow(THREAD_AND_LOCATION, |
|
283 validationException, |
|
284 "Type %s is not a nest member of %s: %s", |
|
285 this->external_name(), |
|
286 k->external_name(), |
|
287 error |
|
288 ); |
|
289 } |
|
290 return NULL; |
|
291 } else { |
|
292 if (log_is_enabled(Trace, class, nestmates)) { |
|
293 ResourceMark rm(THREAD); |
|
294 log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self", |
|
295 this->external_name()); |
|
296 } |
|
297 // save resolved nest-host value |
|
298 return (_nest_host = this); |
|
299 } |
|
300 } |
|
301 return nest_host_k; |
|
302 } |
|
303 |
|
304 // check if 'this' and k are nestmates (same nest_host), or k is our nest_host, |
|
305 // or we are k's nest_host - all of which is covered by comparing the two |
|
306 // resolved_nest_hosts |
|
307 bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) { |
|
308 |
|
309 assert(this != k, "this should be handled by higher-level code"); |
|
310 |
|
311 // Per JVMS 5.4.4 we first resolve and validate the current class, then |
|
312 // the target class k. Resolution exceptions will be passed on by upper |
|
313 // layers. IncompatibleClassChangeErrors from membership validation failures |
|
314 // will also be passed through. |
|
315 |
|
316 Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError(); |
|
317 InstanceKlass* cur_host = nest_host(icce, CHECK_false); |
|
318 if (cur_host == NULL) { |
|
319 return false; |
|
320 } |
|
321 |
|
322 Klass* k_nest_host = k->nest_host(icce, CHECK_false); |
|
323 if (k_nest_host == NULL) { |
|
324 return false; |
|
325 } |
|
326 |
|
327 bool access = (cur_host == k_nest_host); |
|
328 |
|
329 if (log_is_enabled(Trace, class, nestmates)) { |
|
330 ResourceMark rm(THREAD); |
|
331 log_trace(class, nestmates)("Class %s does %shave nestmate access to %s", |
|
332 this->external_name(), |
|
333 access ? "" : "NOT ", |
|
334 k->external_name()); |
|
335 } |
|
336 |
|
337 return access; |
|
338 } |
|
339 |
|
148 InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) { |
340 InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) { |
149 const int size = InstanceKlass::size(parser.vtable_size(), |
341 const int size = InstanceKlass::size(parser.vtable_size(), |
150 parser.itable_size(), |
342 parser.itable_size(), |
151 nonstatic_oop_map_size(parser.total_oop_map_count()), |
343 nonstatic_oop_map_size(parser.total_oop_map_count()), |
152 parser.is_interface(), |
344 parser.is_interface(), |
167 ik = new (loader_data, size, THREAD) InstanceMirrorKlass(parser); |
359 ik = new (loader_data, size, THREAD) InstanceMirrorKlass(parser); |
168 } |
360 } |
169 else if (is_class_loader(class_name, parser)) { |
361 else if (is_class_loader(class_name, parser)) { |
170 // class loader |
362 // class loader |
171 ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass(parser); |
363 ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass(parser); |
172 } |
364 } else { |
173 else { |
|
174 // normal |
365 // normal |
175 ik = new (loader_data, size, THREAD) InstanceKlass(parser, InstanceKlass::_misc_kind_other); |
366 ik = new (loader_data, size, THREAD) InstanceKlass(parser, InstanceKlass::_misc_kind_other); |
176 } |
367 } |
177 } |
368 } else { |
178 else { |
|
179 // reference |
369 // reference |
180 ik = new (loader_data, size, THREAD) InstanceRefKlass(parser); |
370 ik = new (loader_data, size, THREAD) InstanceRefKlass(parser); |
181 } |
371 } |
182 |
372 |
183 // Check for pending exception before adding to the loader data and incrementing |
373 // Check for pending exception before adding to the loader data and incrementing |
213 |
403 |
214 InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind) : |
404 InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind) : |
215 _static_field_size(parser.static_field_size()), |
405 _static_field_size(parser.static_field_size()), |
216 _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())), |
406 _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())), |
217 _itable_len(parser.itable_size()), |
407 _itable_len(parser.itable_size()), |
218 _reference_type(parser.reference_type()) { |
408 _reference_type(parser.reference_type()), |
409 _nest_members(NULL), |
|
410 _nest_host_index(0), |
|
411 _nest_host(NULL) { |
|
219 set_vtable_length(parser.vtable_size()); |
412 set_vtable_length(parser.vtable_size()); |
220 set_kind(kind); |
413 set_kind(kind); |
221 set_access_flags(parser.access_flags()); |
414 set_access_flags(parser.access_flags()); |
222 set_is_anonymous(parser.is_anonymous()); |
415 set_is_anonymous(parser.is_anonymous()); |
223 set_layout_helper(Klass::instance_layout_helper(parser.layout_size(), |
416 set_layout_helper(Klass::instance_layout_helper(parser.layout_size(), |
356 inner_classes() != Universe::the_empty_short_array() && |
549 inner_classes() != Universe::the_empty_short_array() && |
357 !inner_classes()->is_shared()) { |
550 !inner_classes()->is_shared()) { |
358 MetadataFactory::free_array<jushort>(loader_data, inner_classes()); |
551 MetadataFactory::free_array<jushort>(loader_data, inner_classes()); |
359 } |
552 } |
360 set_inner_classes(NULL); |
553 set_inner_classes(NULL); |
554 |
|
555 if (nest_members() != NULL && |
|
556 nest_members() != Universe::the_empty_short_array() && |
|
557 !nest_members()->is_shared()) { |
|
558 MetadataFactory::free_array<jushort>(loader_data, nest_members()); |
|
559 } |
|
560 set_nest_members(NULL); |
|
361 |
561 |
362 // We should deallocate the Annotations instance if it's not in shared spaces. |
562 // We should deallocate the Annotations instance if it's not in shared spaces. |
363 if (annotations() != NULL && !annotations()->is_shared()) { |
563 if (annotations() != NULL && !annotations()->is_shared()) { |
364 MetadataFactory::free_metadata(loader_data, annotations()); |
564 MetadataFactory::free_metadata(loader_data, annotations()); |
365 } |
565 } |
641 } |
841 } |
642 } |
842 } |
643 return true; |
843 return true; |
644 } |
844 } |
645 |
845 |
646 |
|
647 // Rewrite the byte codes of all of the methods of a class. |
846 // Rewrite the byte codes of all of the methods of a class. |
648 // The rewriter must be called exactly once. Rewriting must happen after |
847 // The rewriter must be called exactly once. Rewriting must happen after |
649 // verification but before the first method of the class is executed. |
848 // verification but before the first method of the class is executed. |
650 void InstanceKlass::rewrite_class(TRAPS) { |
849 void InstanceKlass::rewrite_class(TRAPS) { |
651 assert(is_loaded(), "must be loaded"); |
850 assert(is_loaded(), "must be loaded"); |
1357 |
1556 |
1358 // find_instance_method looks up the name/signature in the local methods array |
1557 // find_instance_method looks up the name/signature in the local methods array |
1359 // and skips over static methods |
1558 // and skips over static methods |
1360 Method* InstanceKlass::find_instance_method(const Array<Method*>* methods, |
1559 Method* InstanceKlass::find_instance_method(const Array<Method*>* methods, |
1361 const Symbol* name, |
1560 const Symbol* name, |
1362 const Symbol* signature) { |
1561 const Symbol* signature, |
1562 PrivateLookupMode private_mode) { |
|
1363 Method* const meth = InstanceKlass::find_method_impl(methods, |
1563 Method* const meth = InstanceKlass::find_method_impl(methods, |
1364 name, |
1564 name, |
1365 signature, |
1565 signature, |
1366 find_overpass, |
1566 find_overpass, |
1367 skip_static, |
1567 skip_static, |
1368 find_private); |
1568 private_mode); |
1369 assert(((meth == NULL) || !meth->is_static()), |
1569 assert(((meth == NULL) || !meth->is_static()), |
1370 "find_instance_method should have skipped statics"); |
1570 "find_instance_method should have skipped statics"); |
1371 return meth; |
1571 return meth; |
1372 } |
1572 } |
1373 |
1573 |
1374 // find_instance_method looks up the name/signature in the local methods array |
1574 // find_instance_method looks up the name/signature in the local methods array |
1375 // and skips over static methods |
1575 // and skips over static methods |
1376 Method* InstanceKlass::find_instance_method(const Symbol* name, const Symbol* signature) const { |
1576 Method* InstanceKlass::find_instance_method(const Symbol* name, |
1377 return InstanceKlass::find_instance_method(methods(), name, signature); |
1577 const Symbol* signature, |
1578 PrivateLookupMode private_mode) const { |
|
1579 return InstanceKlass::find_instance_method(methods(), name, signature, private_mode); |
|
1378 } |
1580 } |
1379 |
1581 |
1380 // Find looks up the name/signature in the local methods array |
1582 // Find looks up the name/signature in the local methods array |
1381 // and filters on the overpass, static and private flags |
1583 // and filters on the overpass, static and private flags |
1382 // This returns the first one found |
1584 // This returns the first one found |
1473 const Method* const m = methods->at(hit); |
1675 const Method* const m = methods->at(hit); |
1474 |
1676 |
1475 // Do linear search to find matching signature. First, quick check |
1677 // Do linear search to find matching signature. First, quick check |
1476 // for common case, ignoring overpasses if requested. |
1678 // for common case, ignoring overpasses if requested. |
1477 if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) { |
1679 if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) { |
1478 return hit; |
1680 return hit; |
1479 } |
1681 } |
1480 |
1682 |
1481 // search downwards through overloaded methods |
1683 // search downwards through overloaded methods |
1482 int i; |
1684 int i; |
1483 for (i = hit - 1; i >= 0; --i) { |
1685 for (i = hit - 1; i >= 0; --i) { |
1529 } |
1731 } |
1530 return -1; |
1732 return -1; |
1531 } |
1733 } |
1532 |
1734 |
1533 // uncached_lookup_method searches both the local class methods array and all |
1735 // uncached_lookup_method searches both the local class methods array and all |
1534 // superclasses methods arrays, skipping any overpass methods in superclasses. |
1736 // superclasses methods arrays, skipping any overpass methods in superclasses, |
1737 // and possibly skipping private methods. |
|
1535 Method* InstanceKlass::uncached_lookup_method(const Symbol* name, |
1738 Method* InstanceKlass::uncached_lookup_method(const Symbol* name, |
1536 const Symbol* signature, |
1739 const Symbol* signature, |
1537 OverpassLookupMode overpass_mode) const { |
1740 OverpassLookupMode overpass_mode, |
1741 PrivateLookupMode private_mode) const { |
|
1538 OverpassLookupMode overpass_local_mode = overpass_mode; |
1742 OverpassLookupMode overpass_local_mode = overpass_mode; |
1539 const Klass* klass = this; |
1743 const Klass* klass = this; |
1540 while (klass != NULL) { |
1744 while (klass != NULL) { |
1541 Method* const method = InstanceKlass::cast(klass)->find_method_impl(name, |
1745 Method* const method = InstanceKlass::cast(klass)->find_method_impl(name, |
1542 signature, |
1746 signature, |
1543 overpass_local_mode, |
1747 overpass_local_mode, |
1544 find_static, |
1748 find_static, |
1545 find_private); |
1749 private_mode); |
1546 if (method != NULL) { |
1750 if (method != NULL) { |
1547 return method; |
1751 return method; |
1548 } |
1752 } |
1549 klass = klass->super(); |
1753 klass = klass->super(); |
1550 overpass_local_mode = skip_overpass; // Always ignore overpass methods in superclasses |
1754 overpass_local_mode = skip_overpass; // Always ignore overpass methods in superclasses |
2042 it->push(ime[index].method_addr()); |
2246 it->push(ime[index].method_addr()); |
2043 } |
2247 } |
2044 } |
2248 } |
2045 } |
2249 } |
2046 } |
2250 } |
2251 |
|
2252 it->push(&_nest_members); |
|
2047 } |
2253 } |
2048 |
2254 |
2049 void InstanceKlass::remove_unshareable_info() { |
2255 void InstanceKlass::remove_unshareable_info() { |
2050 Klass::remove_unshareable_info(); |
2256 Klass::remove_unshareable_info(); |
2051 |
2257 |
2085 #if INCLUDE_JVMTI |
2291 #if INCLUDE_JVMTI |
2086 guarantee(_breakpoints == NULL, "must be"); |
2292 guarantee(_breakpoints == NULL, "must be"); |
2087 guarantee(_previous_versions == NULL, "must be"); |
2293 guarantee(_previous_versions == NULL, "must be"); |
2088 #endif |
2294 #endif |
2089 |
2295 |
2090 _init_thread = NULL; |
2296 _init_thread = NULL; |
2091 _methods_jmethod_ids = NULL; |
2297 _methods_jmethod_ids = NULL; |
2092 _jni_ids = NULL; |
2298 _jni_ids = NULL; |
2093 _oop_map_cache = NULL; |
2299 _oop_map_cache = NULL; |
2300 // clear _nest_host to ensure re-load at runtime |
|
2301 _nest_host = NULL; |
|
2094 } |
2302 } |
2095 |
2303 |
2096 void InstanceKlass::remove_java_mirror() { |
2304 void InstanceKlass::remove_java_mirror() { |
2097 Klass::remove_java_mirror(); |
2305 Klass::remove_java_mirror(); |
2098 |
2306 |
2944 st->print(BULLET"generic signature: "); |
3152 st->print(BULLET"generic signature: "); |
2945 generic_signature()->print_value_on(st); |
3153 generic_signature()->print_value_on(st); |
2946 st->cr(); |
3154 st->cr(); |
2947 } |
3155 } |
2948 st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr(); |
3156 st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr(); |
3157 st->print(BULLET"nest members: "); nest_members()->print_value_on(st); st->cr(); |
|
2949 st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr(); |
3158 st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr(); |
2950 st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), p2i(start_of_vtable())); st->cr(); |
3159 st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), p2i(start_of_vtable())); st->cr(); |
2951 if (vtable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_vtable(), vtable_length(), st); |
3160 if (vtable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_vtable(), vtable_length(), st); |
2952 st->print(BULLET"itable length %d (start addr: " INTPTR_FORMAT ")", itable_length(), p2i(start_of_itable())); st->cr(); |
3161 st->print(BULLET"itable length %d (start addr: " INTPTR_FORMAT ")", itable_length(), p2i(start_of_itable())); st->cr(); |
2953 if (itable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_itable(), itable_length(), st); |
3162 if (itable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_itable(), itable_length(), st); |
3186 n += (sz->_method_ordering_bytes = sz->count_array(method_ordering())); |
3395 n += (sz->_method_ordering_bytes = sz->count_array(method_ordering())); |
3187 n += (sz->_local_interfaces_bytes = sz->count_array(local_interfaces())); |
3396 n += (sz->_local_interfaces_bytes = sz->count_array(local_interfaces())); |
3188 n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces())); |
3397 n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces())); |
3189 n += (sz->_fields_bytes = sz->count_array(fields())); |
3398 n += (sz->_fields_bytes = sz->count_array(fields())); |
3190 n += (sz->_inner_classes_bytes = sz->count_array(inner_classes())); |
3399 n += (sz->_inner_classes_bytes = sz->count_array(inner_classes())); |
3400 n += (sz->_nest_members_bytes = sz->count_array(nest_members())); |
|
3191 sz->_ro_bytes += n; |
3401 sz->_ro_bytes += n; |
3192 |
3402 |
3193 const ConstantPool* cp = constants(); |
3403 const ConstantPool* cp = constants(); |
3194 if (cp) { |
3404 if (cp) { |
3195 cp->collect_statistics(sz); |
3405 cp->collect_statistics(sz); |