mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
Pass arguments to runtime via java array for arrays with > 5 dimensions Reviewed-by: never, kvn, jrose, pbk
This commit is contained in:
parent
20a26c54cd
commit
09a3aca98b
3 changed files with 72 additions and 17 deletions
|
@ -417,17 +417,10 @@ void Parse::do_multianewarray() {
|
||||||
|
|
||||||
// Note: Array classes are always initialized; no is_initialized check.
|
// 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();
|
kill_dead_locals();
|
||||||
|
|
||||||
// get the lengths from the stack (first dimension is on top)
|
// 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
|
length[ndimensions] = NULL; // terminating null for make_runtime_call
|
||||||
int j;
|
int j;
|
||||||
for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop();
|
for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop();
|
||||||
|
@ -470,20 +463,43 @@ void Parse::do_multianewarray() {
|
||||||
|
|
||||||
address fun = NULL;
|
address fun = NULL;
|
||||||
switch (ndimensions) {
|
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 2: fun = OptoRuntime::multianewarray2_Java(); break;
|
||||||
case 3: fun = OptoRuntime::multianewarray3_Java(); break;
|
case 3: fun = OptoRuntime::multianewarray3_Java(); break;
|
||||||
case 4: fun = OptoRuntime::multianewarray4_Java(); break;
|
case 4: fun = OptoRuntime::multianewarray4_Java(); break;
|
||||||
case 5: fun = OptoRuntime::multianewarray5_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));
|
Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms));
|
||||||
|
|
||||||
const Type* type = TypeOopPtr::make_from_klass_raw(array_klass);
|
const Type* type = TypeOopPtr::make_from_klass_raw(array_klass);
|
||||||
|
@ -496,7 +512,7 @@ void Parse::do_multianewarray() {
|
||||||
if (ltype != NULL)
|
if (ltype != NULL)
|
||||||
type = type->is_aryptr()->cast_to_size(ltype);
|
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) );
|
Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) );
|
||||||
push(cast);
|
push(cast);
|
||||||
|
|
|
@ -106,6 +106,7 @@ address OptoRuntime::_multianewarray2_Java = NULL;
|
||||||
address OptoRuntime::_multianewarray3_Java = NULL;
|
address OptoRuntime::_multianewarray3_Java = NULL;
|
||||||
address OptoRuntime::_multianewarray4_Java = NULL;
|
address OptoRuntime::_multianewarray4_Java = NULL;
|
||||||
address OptoRuntime::_multianewarray5_Java = NULL;
|
address OptoRuntime::_multianewarray5_Java = NULL;
|
||||||
|
address OptoRuntime::_multianewarrayN_Java = NULL;
|
||||||
address OptoRuntime::_g1_wb_pre_Java = NULL;
|
address OptoRuntime::_g1_wb_pre_Java = NULL;
|
||||||
address OptoRuntime::_g1_wb_post_Java = NULL;
|
address OptoRuntime::_g1_wb_post_Java = NULL;
|
||||||
address OptoRuntime::_vtable_must_compile_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, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true , false, false);
|
||||||
gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_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, _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_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, _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);
|
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);
|
thread->set_vm_result(obj);
|
||||||
JRT_END
|
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() {
|
const TypeFunc *OptoRuntime::new_instance_Type() {
|
||||||
// create input type (domain)
|
// create input type (domain)
|
||||||
const Type **fields = TypeTuple::fields(1);
|
const Type **fields = TypeTuple::fields(1);
|
||||||
|
@ -454,6 +474,21 @@ const TypeFunc *OptoRuntime::multianewarray5_Type() {
|
||||||
return multianewarray_Type(5);
|
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 TypeFunc *OptoRuntime::g1_wb_pre_Type() {
|
||||||
const Type **fields = TypeTuple::fields(2);
|
const Type **fields = TypeTuple::fields(2);
|
||||||
fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
|
fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
|
||||||
|
|
|
@ -118,6 +118,7 @@ class OptoRuntime : public AllStatic {
|
||||||
static address _multianewarray3_Java;
|
static address _multianewarray3_Java;
|
||||||
static address _multianewarray4_Java;
|
static address _multianewarray4_Java;
|
||||||
static address _multianewarray5_Java;
|
static address _multianewarray5_Java;
|
||||||
|
static address _multianewarrayN_Java;
|
||||||
static address _g1_wb_pre_Java;
|
static address _g1_wb_pre_Java;
|
||||||
static address _g1_wb_post_Java;
|
static address _g1_wb_post_Java;
|
||||||
static address _vtable_must_compile_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 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 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 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_pre_C(oopDesc* orig, JavaThread* thread);
|
||||||
static void g1_wb_post_C(void* card_addr, 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 multianewarray3_Java() { return _multianewarray3_Java; }
|
||||||
static address multianewarray4_Java() { return _multianewarray4_Java; }
|
static address multianewarray4_Java() { return _multianewarray4_Java; }
|
||||||
static address multianewarray5_Java() { return _multianewarray5_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_pre_Java() { return _g1_wb_pre_Java; }
|
||||||
static address g1_wb_post_Java() { return _g1_wb_post_Java; }
|
static address g1_wb_post_Java() { return _g1_wb_post_Java; }
|
||||||
static address vtable_must_compile_stub() { return _vtable_must_compile_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* multianewarray3_Type(); // multianewarray
|
||||||
static const TypeFunc* multianewarray4_Type(); // multianewarray
|
static const TypeFunc* multianewarray4_Type(); // multianewarray
|
||||||
static const TypeFunc* multianewarray5_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_pre_Type();
|
||||||
static const TypeFunc* g1_wb_post_Type();
|
static const TypeFunc* g1_wb_post_Type();
|
||||||
static const TypeFunc* complete_monitor_enter_Type();
|
static const TypeFunc* complete_monitor_enter_Type();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue