8046542: [I.finalize() calls from methods compiled by C1 do not cause IllegalAccessError on Sparc
Summary: call to Object.finalize() sometimes allowed by compilers on array type
Reviewed-by: iveresov, vlivanov
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Tue Jul 01 13:09:40 2014 +0400
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jul 02 22:54:18 2014 +0200
@@ -1997,7 +1997,13 @@
if (!UseInlineCaches && is_loaded && code == Bytecodes::_invokevirtual
&& !target->can_be_statically_bound()) {
// Find a vtable index if one is available
- vtable_index = target->resolve_vtable_index(calling_klass, callee_holder);
+ // For arrays, callee_holder is Object. Resolving the call with
+ // Object would allow an illegal call to finalize() on an
+ // array. We use holder instead: illegal calls to finalize() won't
+ // be compiled as vtable calls (IC call resolution will catch the
+ // illegal call) and the few legal calls on array types won't be
+ // either.
+ vtable_index = target->resolve_vtable_index(calling_klass, holder);
}
#endif
--- a/hotspot/src/share/vm/opto/callGenerator.cpp Tue Jul 01 13:09:40 2014 +0400
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp Wed Jul 02 22:54:18 2014 +0200
@@ -871,8 +871,11 @@
Node* receiver_node = kit.argument(0);
const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr();
// call_does_dispatch and vtable_index are out-parameters. They might be changed.
- target = C->optimize_virtual_call(caller, jvms->bci(), klass, target, receiver_type,
- is_virtual,
+ // optimize_virtual_call() takes 2 different holder
+ // arguments for a corner case that doesn't apply here (see
+ // Parse::do_call())
+ target = C->optimize_virtual_call(caller, jvms->bci(), klass, klass,
+ target, receiver_type, is_virtual,
call_does_dispatch, vtable_index); // out-parameters
// We lack profiling at this call but type speculation may
// provide us with a type
--- a/hotspot/src/share/vm/opto/compile.hpp Tue Jul 01 13:09:40 2014 +0400
+++ b/hotspot/src/share/vm/opto/compile.hpp Wed Jul 02 22:54:18 2014 +0200
@@ -852,8 +852,8 @@
// Helper functions to identify inlining potential at call-site
ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
- ciMethod* callee, const TypeOopPtr* receiver_type,
- bool is_virtual,
+ ciKlass* holder, ciMethod* callee,
+ const TypeOopPtr* receiver_type, bool is_virtual,
bool &call_does_dispatch, int &vtable_index);
ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass,
ciMethod* callee, const TypeOopPtr* receiver_type);
--- a/hotspot/src/share/vm/opto/doCall.cpp Tue Jul 01 13:09:40 2014 +0400
+++ b/hotspot/src/share/vm/opto/doCall.cpp Wed Jul 02 22:54:18 2014 +0200
@@ -468,8 +468,14 @@
Node* receiver_node = stack(sp() - nargs);
const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr();
// call_does_dispatch and vtable_index are out-parameters. They might be changed.
- callee = C->optimize_virtual_call(method(), bci(), klass, orig_callee, receiver_type,
- is_virtual,
+ // For arrays, klass below is Object. When vtable calls are used,
+ // resolving the call with Object would allow an illegal call to
+ // finalize() on an array. We use holder instead: illegal calls to
+ // finalize() won't be compiled as vtable calls (IC call
+ // resolution will catch the illegal call) and the few legal calls
+ // on array types won't be either.
+ callee = C->optimize_virtual_call(method(), bci(), klass, holder, orig_callee,
+ receiver_type, is_virtual,
call_does_dispatch, vtable_index); // out-parameters
speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL;
}
@@ -940,8 +946,8 @@
ciMethod* Compile::optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
- ciMethod* callee, const TypeOopPtr* receiver_type,
- bool is_virtual,
+ ciKlass* holder, ciMethod* callee,
+ const TypeOopPtr* receiver_type, bool is_virtual,
bool& call_does_dispatch, int& vtable_index) {
// Set default values for out-parameters.
call_does_dispatch = true;
@@ -956,7 +962,7 @@
call_does_dispatch = false;
} else if (!UseInlineCaches && is_virtual && callee->is_loaded()) {
// We can make a vtable call at this site
- vtable_index = callee->resolve_vtable_index(caller->holder(), klass);
+ vtable_index = callee->resolve_vtable_index(caller->holder(), holder);
}
return callee;
}
@@ -979,8 +985,10 @@
ciInstanceKlass* actual_receiver = klass;
if (receiver_type != NULL) {
// Array methods are all inherited from Object, and are monomorphic.
+ // finalize() call on array is not allowed.
if (receiver_type->isa_aryptr() &&
- callee->holder() == env()->Object_klass()) {
+ callee->holder() == env()->Object_klass() &&
+ callee->name() != ciSymbol::finalize_method_name()) {
return callee;
}