# HG changeset patch # User roland # Date 1404334458 -7200 # Node ID c18718ecf276ed320e9b829dfad08c3413599d29 # Parent d50969e815688395f6fff34f3b6c4d4b2c81d330 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 diff -r d50969e81568 -r c18718ecf276 hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- 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 diff -r d50969e81568 -r c18718ecf276 hotspot/src/share/vm/opto/callGenerator.cpp --- 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 diff -r d50969e81568 -r c18718ecf276 hotspot/src/share/vm/opto/compile.hpp --- 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); diff -r d50969e81568 -r c18718ecf276 hotspot/src/share/vm/opto/doCall.cpp --- 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; }