mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 20:44:41 +02:00
8046542: [I.finalize() calls from methods compiled by C1 do not cause IllegalAccessError on Sparc
Call to Object.finalize() sometimes allowed by compilers on array type Reviewed-by: iveresov, vlivanov
This commit is contained in:
parent
0231fb818f
commit
b5e96ad985
4 changed files with 28 additions and 11 deletions
|
@ -1997,7 +1997,13 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
|
||||||
if (!UseInlineCaches && is_loaded && code == Bytecodes::_invokevirtual
|
if (!UseInlineCaches && is_loaded && code == Bytecodes::_invokevirtual
|
||||||
&& !target->can_be_statically_bound()) {
|
&& !target->can_be_statically_bound()) {
|
||||||
// Find a vtable index if one is available
|
// 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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -871,8 +871,11 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod*
|
||||||
Node* receiver_node = kit.argument(0);
|
Node* receiver_node = kit.argument(0);
|
||||||
const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr();
|
const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr();
|
||||||
// call_does_dispatch and vtable_index are out-parameters. They might be changed.
|
// 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,
|
// optimize_virtual_call() takes 2 different holder
|
||||||
is_virtual,
|
// 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
|
call_does_dispatch, vtable_index); // out-parameters
|
||||||
// We lack profiling at this call but type speculation may
|
// We lack profiling at this call but type speculation may
|
||||||
// provide us with a type
|
// provide us with a type
|
||||||
|
|
|
@ -852,8 +852,8 @@ class Compile : public Phase {
|
||||||
|
|
||||||
// Helper functions to identify inlining potential at call-site
|
// Helper functions to identify inlining potential at call-site
|
||||||
ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
|
ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
|
||||||
ciMethod* callee, const TypeOopPtr* receiver_type,
|
ciKlass* holder, ciMethod* callee,
|
||||||
bool is_virtual,
|
const TypeOopPtr* receiver_type, bool is_virtual,
|
||||||
bool &call_does_dispatch, int &vtable_index);
|
bool &call_does_dispatch, int &vtable_index);
|
||||||
ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass,
|
ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass,
|
||||||
ciMethod* callee, const TypeOopPtr* receiver_type);
|
ciMethod* callee, const TypeOopPtr* receiver_type);
|
||||||
|
|
|
@ -468,8 +468,14 @@ void Parse::do_call() {
|
||||||
Node* receiver_node = stack(sp() - nargs);
|
Node* receiver_node = stack(sp() - nargs);
|
||||||
const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr();
|
const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr();
|
||||||
// call_does_dispatch and vtable_index are out-parameters. They might be changed.
|
// 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,
|
// For arrays, klass below is Object. When vtable calls are used,
|
||||||
is_virtual,
|
// 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
|
call_does_dispatch, vtable_index); // out-parameters
|
||||||
speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL;
|
speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL;
|
||||||
}
|
}
|
||||||
|
@ -940,8 +946,8 @@ void Parse::count_compiled_calls(bool at_method_entry, bool is_inline) {
|
||||||
|
|
||||||
|
|
||||||
ciMethod* Compile::optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
|
ciMethod* Compile::optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
|
||||||
ciMethod* callee, const TypeOopPtr* receiver_type,
|
ciKlass* holder, ciMethod* callee,
|
||||||
bool is_virtual,
|
const TypeOopPtr* receiver_type, bool is_virtual,
|
||||||
bool& call_does_dispatch, int& vtable_index) {
|
bool& call_does_dispatch, int& vtable_index) {
|
||||||
// Set default values for out-parameters.
|
// Set default values for out-parameters.
|
||||||
call_does_dispatch = true;
|
call_does_dispatch = true;
|
||||||
|
@ -956,7 +962,7 @@ ciMethod* Compile::optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKl
|
||||||
call_does_dispatch = false;
|
call_does_dispatch = false;
|
||||||
} else if (!UseInlineCaches && is_virtual && callee->is_loaded()) {
|
} else if (!UseInlineCaches && is_virtual && callee->is_loaded()) {
|
||||||
// We can make a vtable call at this site
|
// 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;
|
return callee;
|
||||||
}
|
}
|
||||||
|
@ -979,8 +985,10 @@ ciMethod* Compile::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass*
|
||||||
ciInstanceKlass* actual_receiver = klass;
|
ciInstanceKlass* actual_receiver = klass;
|
||||||
if (receiver_type != NULL) {
|
if (receiver_type != NULL) {
|
||||||
// Array methods are all inherited from Object, and are monomorphic.
|
// Array methods are all inherited from Object, and are monomorphic.
|
||||||
|
// finalize() call on array is not allowed.
|
||||||
if (receiver_type->isa_aryptr() &&
|
if (receiver_type->isa_aryptr() &&
|
||||||
callee->holder() == env()->Object_klass()) {
|
callee->holder() == env()->Object_klass() &&
|
||||||
|
callee->name() != ciSymbol::finalize_method_name()) {
|
||||||
return callee;
|
return callee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue