< prev index next >
src/hotspot/share/oops/method.cpp
Print this page
@@ -495,10 +495,56 @@
assert(k != NULL && !thread->has_pending_exception(), "can't resolve klass");
return ValueKlass::cast(k);
}
#endif
+void Method::check_returning_vt(TRAPS) {
+ ResourceMark rm(THREAD);
+ SignatureStream ss(signature());
+ while (!ss.at_return_type()) {
+ ss.next();
+ }
+ assert(ss.is_object(), "should be called only if the return type is known to be an object");
+
+ Handle class_loader(THREAD, method_holder()->class_loader());
+ Handle protection_domain(THREAD, method_holder()->protection_domain());
+ Symbol* return_class_name = ss.as_symbol(CHECK);
+ Klass* k = SystemDictionary::find(return_class_name, class_loader, protection_domain, CHECK);
+ assert(!THREAD->has_pending_exception(), "can't resolve klass");
+
+ if (k != NULL) {
+ if (k->is_value()) {
+ set_known_returning_vt();
+ } else {
+ set_known_not_returning_vt();
+ }
+ } else {
+ // set_known_not_returning_vt(); // <<- enable this and RarelyUsedValueUser.doit() will crash.
+ // We are still not sure if the return type is a VT. This could happen
+ // when we call a method whose return type has not yet been resolved:
+ //
+ // public /*non-VT-aware*/ class Foo {
+ // SomeType doit() { return null; }
+ // public static void main(String args[]) {doit(); doit(); doit(); }
+ // }
+ //
+ // Normally, if SomeType is a VT, it will be included in Foo's "ValueTypes"
+ // attribute, which means SomeType is eagerly resolved when Foo
+ // is loaded.
+ //
+ // However, we might have a Foo class that's not VT-aware, so it doesn't have
+ // a "ValueTypes" attribute, which means SomeType may not be loaded
+ // before Foo.doit() is called.
+ //
+ // Also, we cannot simply assume that SomeType is not a VT, because Foo may
+ // be a hand-written class that elides the "ValueTypes" attribute on purpose.
+ //
+ // This means that in some rare cases we might call check_returning_vt()
+ // repeatedly (3 times in the examples above).
+ }
+}
+
bool Method::is_empty_method() const {
return code_size() == 1
&& *code_base() == Bytecodes::_return;
}
< prev index next >