8046542: [I.finalize() calls from methods compiled by C1 do not cause IllegalAccessError on Sparc
authorroland
Wed, 02 Jul 2014 22:54:18 +0200
changeset 25494 c18718ecf276
parent 25379 d50969e81568
child 25495 aeb87692dfd0
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
hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
hotspot/src/share/vm/opto/callGenerator.cpp
hotspot/src/share/vm/opto/compile.hpp
hotspot/src/share/vm/opto/doCall.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
 
--- 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;
     }