changeset 2567:263247c478c5

7058510: multinewarray with 6 dimensions uncommon traps in server compiler Summary: Pass arguments to runtime via java array for arrays with > 5 dimensions Reviewed-by: never, kvn, jrose, pbk
author iveresov
date Fri, 08 Jul 2011 15:33:03 -0700
parents faa472957b38
children 1f4f4ae84625
files src/share/vm/opto/parse3.cpp src/share/vm/opto/runtime.cpp src/share/vm/opto/runtime.hpp
diffstat 3 files changed, 72 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/parse3.cpp	Fri Jul 08 09:38:48 2011 -0700
+++ b/src/share/vm/opto/parse3.cpp	Fri Jul 08 15:33:03 2011 -0700
@@ -417,17 +417,10 @@
 
   // Note:  Array classes are always initialized; no is_initialized check.
 
-  enum { MAX_DIMENSION = 5 };
-  if (ndimensions > MAX_DIMENSION || ndimensions <= 0) {
-    uncommon_trap(Deoptimization::Reason_unhandled,
-                  Deoptimization::Action_none);
-    return;
-  }
-
   kill_dead_locals();
 
   // get the lengths from the stack (first dimension is on top)
-  Node* length[MAX_DIMENSION+1];
+  Node** length = NEW_RESOURCE_ARRAY(Node*, ndimensions + 1);
   length[ndimensions] = NULL;  // terminating null for make_runtime_call
   int j;
   for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop();
@@ -470,20 +463,43 @@
 
   address fun = NULL;
   switch (ndimensions) {
-  //case 1: Actually, there is no case 1.  It's handled by new_array.
+  case 1: ShouldNotReachHere(); break;
   case 2: fun = OptoRuntime::multianewarray2_Java(); break;
   case 3: fun = OptoRuntime::multianewarray3_Java(); break;
   case 4: fun = OptoRuntime::multianewarray4_Java(); break;
   case 5: fun = OptoRuntime::multianewarray5_Java(); break;
-  default: ShouldNotReachHere();
   };
+  Node* c = NULL;
 
-  Node* c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
-                              OptoRuntime::multianewarray_Type(ndimensions),
-                              fun, NULL, TypeRawPtr::BOTTOM,
-                              makecon(TypeKlassPtr::make(array_klass)),
-                              length[0], length[1], length[2],
-                              length[3], length[4]);
+  if (fun != NULL) {
+    c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
+                          OptoRuntime::multianewarray_Type(ndimensions),
+                          fun, NULL, TypeRawPtr::BOTTOM,
+                          makecon(TypeKlassPtr::make(array_klass)),
+                          length[0], length[1], length[2],
+                          length[3], length[4]);
+  } else {
+    // Create a java array for dimension sizes
+    Node* dims = NULL;
+    { PreserveReexecuteState preexecs(this);
+      _sp += ndimensions;
+      Node* dims_array_klass = makecon(TypeKlassPtr::make(ciArrayKlass::make(ciType::make(T_INT))));
+      dims = new_array(dims_array_klass, intcon(ndimensions), 0);
+
+      // Fill-in it with values
+      for (j = 0; j < ndimensions; j++) {
+        Node *dims_elem = array_element_address(dims, intcon(j), T_INT);
+        store_to_memory(control(), dims_elem, length[j], T_INT, TypeAryPtr::INTS);
+      }
+    }
+
+    c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
+                          OptoRuntime::multianewarrayN_Type(),
+                          OptoRuntime::multianewarrayN_Java(), NULL, TypeRawPtr::BOTTOM,
+                          makecon(TypeKlassPtr::make(array_klass)),
+                          dims);
+  }
+
   Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms));
 
   const Type* type = TypeOopPtr::make_from_klass_raw(array_klass);
@@ -496,7 +512,7 @@
   if (ltype != NULL)
     type = type->is_aryptr()->cast_to_size(ltype);
 
-  // We cannot sharpen the nested sub-arrays, since the top level is mutable.
+    // We cannot sharpen the nested sub-arrays, since the top level is mutable.
 
   Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) );
   push(cast);
--- a/src/share/vm/opto/runtime.cpp	Fri Jul 08 09:38:48 2011 -0700
+++ b/src/share/vm/opto/runtime.cpp	Fri Jul 08 15:33:03 2011 -0700
@@ -106,6 +106,7 @@
 address OptoRuntime::_multianewarray3_Java                        = NULL;
 address OptoRuntime::_multianewarray4_Java                        = NULL;
 address OptoRuntime::_multianewarray5_Java                        = NULL;
+address OptoRuntime::_multianewarrayN_Java                        = NULL;
 address OptoRuntime::_g1_wb_pre_Java                              = NULL;
 address OptoRuntime::_g1_wb_post_Java                             = NULL;
 address OptoRuntime::_vtable_must_compile_Java                    = NULL;
@@ -154,6 +155,7 @@
   gen(env, _multianewarray3_Java           , multianewarray3_Type         , multianewarray3_C               ,    0 , true , false, false);
   gen(env, _multianewarray4_Java           , multianewarray4_Type         , multianewarray4_C               ,    0 , true , false, false);
   gen(env, _multianewarray5_Java           , multianewarray5_Type         , multianewarray5_C               ,    0 , true , false, false);
+  gen(env, _multianewarrayN_Java           , multianewarrayN_Type         , multianewarrayN_C               ,    0 , true , false, false);
   gen(env, _g1_wb_pre_Java                 , g1_wb_pre_Type               , SharedRuntime::g1_wb_pre        ,    0 , false, false, false);
   gen(env, _g1_wb_post_Java                , g1_wb_post_Type              , SharedRuntime::g1_wb_post       ,    0 , false, false, false);
   gen(env, _complete_monitor_locking_Java  , complete_monitor_enter_Type  , SharedRuntime::complete_monitor_locking_C      ,    0 , false, false, false);
@@ -374,6 +376,24 @@
   thread->set_vm_result(obj);
 JRT_END
 
+JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(klassOopDesc* elem_type, arrayOopDesc* dims, JavaThread *thread))
+  assert(check_compiled_frame(thread), "incorrect caller");
+  assert(oop(elem_type)->is_klass(), "not a class");
+  assert(oop(dims)->is_typeArray(), "not an array");
+
+  ResourceMark rm;
+  jint len = dims->length();
+  assert(len > 0, "Dimensions array should contain data");
+  jint *j_dims = typeArrayOop(dims)->int_at_addr(0);
+  jint *c_dims = NEW_RESOURCE_ARRAY(jint, len);
+  Copy::conjoint_jints_atomic(j_dims, c_dims, len);
+
+  oop obj = arrayKlass::cast(elem_type)->multi_allocate(len, c_dims, THREAD);
+  deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
+  thread->set_vm_result(obj);
+JRT_END
+
+
 const TypeFunc *OptoRuntime::new_instance_Type() {
   // create input type (domain)
   const Type **fields = TypeTuple::fields(1);
@@ -454,6 +474,21 @@
   return multianewarray_Type(5);
 }
 
+const TypeFunc *OptoRuntime::multianewarrayN_Type() {
+  // create input type (domain)
+  const Type **fields = TypeTuple::fields(2);
+  fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;   // element klass
+  fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL;   // array of dim sizes
+  const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
+
+  // create result type (range)
+  fields = TypeTuple::fields(1);
+  fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
+  const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
+
+  return TypeFunc::make(domain, range);
+}
+
 const TypeFunc *OptoRuntime::g1_wb_pre_Type() {
   const Type **fields = TypeTuple::fields(2);
   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
--- a/src/share/vm/opto/runtime.hpp	Fri Jul 08 09:38:48 2011 -0700
+++ b/src/share/vm/opto/runtime.hpp	Fri Jul 08 15:33:03 2011 -0700
@@ -118,6 +118,7 @@
   static address _multianewarray3_Java;
   static address _multianewarray4_Java;
   static address _multianewarray5_Java;
+  static address _multianewarrayN_Java;
   static address _g1_wb_pre_Java;
   static address _g1_wb_post_Java;
   static address _vtable_must_compile_Java;
@@ -153,6 +154,7 @@
   static void multianewarray3_C(klassOopDesc* klass, int len1, int len2, int len3, JavaThread *thread);
   static void multianewarray4_C(klassOopDesc* klass, int len1, int len2, int len3, int len4, JavaThread *thread);
   static void multianewarray5_C(klassOopDesc* klass, int len1, int len2, int len3, int len4, int len5, JavaThread *thread);
+  static void multianewarrayN_C(klassOopDesc* klass, arrayOopDesc* dims, JavaThread *thread);
   static void g1_wb_pre_C(oopDesc* orig, JavaThread* thread);
   static void g1_wb_post_C(void* card_addr, JavaThread* thread);
 
@@ -210,6 +212,7 @@
   static address multianewarray3_Java()                  { return _multianewarray3_Java; }
   static address multianewarray4_Java()                  { return _multianewarray4_Java; }
   static address multianewarray5_Java()                  { return _multianewarray5_Java; }
+  static address multianewarrayN_Java()                  { return _multianewarrayN_Java; }
   static address g1_wb_pre_Java()                        { return _g1_wb_pre_Java; }
   static address g1_wb_post_Java()                       { return _g1_wb_post_Java; }
   static address vtable_must_compile_stub()              { return _vtable_must_compile_Java; }
@@ -249,6 +252,7 @@
   static const TypeFunc* multianewarray3_Type(); // multianewarray
   static const TypeFunc* multianewarray4_Type(); // multianewarray
   static const TypeFunc* multianewarray5_Type(); // multianewarray
+  static const TypeFunc* multianewarrayN_Type(); // multianewarray
   static const TypeFunc* g1_wb_pre_Type();
   static const TypeFunc* g1_wb_post_Type();
   static const TypeFunc* complete_monitor_enter_Type();