Wed, 02 Jul 2014 22:54:18 +0200
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
1.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Thu Jul 03 12:59:11 2014 -0700 1.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jul 02 22:54:18 2014 +0200 1.3 @@ -1993,7 +1993,13 @@ 1.4 if (!UseInlineCaches && is_loaded && code == Bytecodes::_invokevirtual 1.5 && !target->can_be_statically_bound()) { 1.6 // Find a vtable index if one is available 1.7 - vtable_index = target->resolve_vtable_index(calling_klass, callee_holder); 1.8 + // For arrays, callee_holder is Object. Resolving the call with 1.9 + // Object would allow an illegal call to finalize() on an 1.10 + // array. We use holder instead: illegal calls to finalize() won't 1.11 + // be compiled as vtable calls (IC call resolution will catch the 1.12 + // illegal call) and the few legal calls on array types won't be 1.13 + // either. 1.14 + vtable_index = target->resolve_vtable_index(calling_klass, holder); 1.15 } 1.16 #endif 1.17
2.1 --- a/src/share/vm/opto/callGenerator.cpp Thu Jul 03 12:59:11 2014 -0700 2.2 +++ b/src/share/vm/opto/callGenerator.cpp Wed Jul 02 22:54:18 2014 +0200 2.3 @@ -837,8 +837,11 @@ 2.4 Node* receiver_node = kit.argument(0); 2.5 const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr(); 2.6 // call_does_dispatch and vtable_index are out-parameters. They might be changed. 2.7 - target = C->optimize_virtual_call(caller, jvms->bci(), klass, target, receiver_type, 2.8 - is_virtual, 2.9 + // optimize_virtual_call() takes 2 different holder 2.10 + // arguments for a corner case that doesn't apply here (see 2.11 + // Parse::do_call()) 2.12 + target = C->optimize_virtual_call(caller, jvms->bci(), klass, klass, 2.13 + target, receiver_type, is_virtual, 2.14 call_does_dispatch, vtable_index); // out-parameters 2.15 // We lack profiling at this call but type speculation may 2.16 // provide us with a type
3.1 --- a/src/share/vm/opto/compile.hpp Thu Jul 03 12:59:11 2014 -0700 3.2 +++ b/src/share/vm/opto/compile.hpp Wed Jul 02 22:54:18 2014 +0200 3.3 @@ -854,8 +854,8 @@ 3.4 3.5 // Helper functions to identify inlining potential at call-site 3.6 ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass, 3.7 - ciMethod* callee, const TypeOopPtr* receiver_type, 3.8 - bool is_virtual, 3.9 + ciKlass* holder, ciMethod* callee, 3.10 + const TypeOopPtr* receiver_type, bool is_virtual, 3.11 bool &call_does_dispatch, int &vtable_index); 3.12 ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, 3.13 ciMethod* callee, const TypeOopPtr* receiver_type);
4.1 --- a/src/share/vm/opto/doCall.cpp Thu Jul 03 12:59:11 2014 -0700 4.2 +++ b/src/share/vm/opto/doCall.cpp Wed Jul 02 22:54:18 2014 +0200 4.3 @@ -460,8 +460,14 @@ 4.4 Node* receiver_node = stack(sp() - nargs); 4.5 const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr(); 4.6 // call_does_dispatch and vtable_index are out-parameters. They might be changed. 4.7 - callee = C->optimize_virtual_call(method(), bci(), klass, orig_callee, receiver_type, 4.8 - is_virtual, 4.9 + // For arrays, klass below is Object. When vtable calls are used, 4.10 + // resolving the call with Object would allow an illegal call to 4.11 + // finalize() on an array. We use holder instead: illegal calls to 4.12 + // finalize() won't be compiled as vtable calls (IC call 4.13 + // resolution will catch the illegal call) and the few legal calls 4.14 + // on array types won't be either. 4.15 + callee = C->optimize_virtual_call(method(), bci(), klass, holder, orig_callee, 4.16 + receiver_type, is_virtual, 4.17 call_does_dispatch, vtable_index); // out-parameters 4.18 speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL; 4.19 } 4.20 @@ -937,8 +943,8 @@ 4.21 4.22 4.23 ciMethod* Compile::optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass, 4.24 - ciMethod* callee, const TypeOopPtr* receiver_type, 4.25 - bool is_virtual, 4.26 + ciKlass* holder, ciMethod* callee, 4.27 + const TypeOopPtr* receiver_type, bool is_virtual, 4.28 bool& call_does_dispatch, int& vtable_index) { 4.29 // Set default values for out-parameters. 4.30 call_does_dispatch = true; 4.31 @@ -953,7 +959,7 @@ 4.32 call_does_dispatch = false; 4.33 } else if (!UseInlineCaches && is_virtual && callee->is_loaded()) { 4.34 // We can make a vtable call at this site 4.35 - vtable_index = callee->resolve_vtable_index(caller->holder(), klass); 4.36 + vtable_index = callee->resolve_vtable_index(caller->holder(), holder); 4.37 } 4.38 return callee; 4.39 } 4.40 @@ -976,8 +982,10 @@ 4.41 ciInstanceKlass* actual_receiver = klass; 4.42 if (receiver_type != NULL) { 4.43 // Array methods are all inherited from Object, and are monomorphic. 4.44 + // finalize() call on array is not allowed. 4.45 if (receiver_type->isa_aryptr() && 4.46 - callee->holder() == env()->Object_klass()) { 4.47 + callee->holder() == env()->Object_klass() && 4.48 + callee->name() != ciSymbol::finalize_method_name()) { 4.49 return callee; 4.50 } 4.51