From 77673a17ed97432ff50fa9f890e0bb51f39cf39c Mon Sep 17 00:00:00 2001 From: iveresov Date: Fri, 8 Jul 2011 15:33:03 -0700 Subject: [PATCH] 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 --- src/share/vm/opto/parse3.cpp | 50 +++++++++++++++++++++++------------ src/share/vm/opto/runtime.cpp | 35 ++++++++++++++++++++++++ src/share/vm/opto/runtime.hpp | 4 +++ 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/src/share/vm/opto/parse3.cpp b/src/share/vm/opto/parse3.cpp index eec5131e1..e1a319fad 100644 --- a/src/share/vm/opto/parse3.cpp +++ b/src/share/vm/opto/parse3.cpp @@ -417,17 +417,10 @@ void Parse::do_multianewarray() { // 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 @@ void Parse::do_multianewarray() { 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; + + 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* 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]); 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 @@ void Parse::do_multianewarray() { 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); diff --git a/src/share/vm/opto/runtime.cpp b/src/share/vm/opto/runtime.cpp index 40f39d7fe..4c55ca0d6 100644 --- a/src/share/vm/opto/runtime.cpp +++ b/src/share/vm/opto/runtime.cpp @@ -106,6 +106,7 @@ address OptoRuntime::_multianewarray2_Java = NULL; 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 @@ void OptoRuntime::generate(ciEnv* env) { 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 @@ JRT_ENTRY(void, OptoRuntime::multianewarray5_C(klassOopDesc* elem_type, int len1 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 @@ const TypeFunc *OptoRuntime::multianewarray5_Type() { 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 diff --git a/src/share/vm/opto/runtime.hpp b/src/share/vm/opto/runtime.hpp index 4d0d21111..a691da307 100644 --- a/src/share/vm/opto/runtime.hpp +++ b/src/share/vm/opto/runtime.hpp @@ -118,6 +118,7 @@ class OptoRuntime : public AllStatic { 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 @@ class OptoRuntime : public AllStatic { 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 @@ private: 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 @@ private: 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(); -- GitLab