提交 8c62e0f3 编写于 作者: T twisti

7157365: jruby/bench.bench_timeout crashes with JVM internal error

Reviewed-by: jrose, kvn
上级 861ebacd
...@@ -273,7 +273,7 @@ class Universe: AllStatic { ...@@ -273,7 +273,7 @@ class Universe: AllStatic {
} }
static klassOop typeArrayKlassObj(BasicType t) { static klassOop typeArrayKlassObj(BasicType t) {
assert((uint)t < T_VOID+1, "range check"); assert((uint)t < T_VOID+1, err_msg("range check for type: %s", type2name(t)));
assert(_typeArrayKlassObjs[t] != NULL, "domain check"); assert(_typeArrayKlassObjs[t] != NULL, "domain check");
return _typeArrayKlassObjs[t]; return _typeArrayKlassObjs[t];
} }
......
...@@ -172,9 +172,11 @@ public: ...@@ -172,9 +172,11 @@ public:
JVMState* DynamicCallGenerator::generate(JVMState* jvms) { JVMState* DynamicCallGenerator::generate(JVMState* jvms) {
GraphKit kit(jvms); GraphKit kit(jvms);
Compile* C = kit.C;
PhaseGVN& gvn = kit.gvn();
if (kit.C->log() != NULL) { if (C->log() != NULL) {
kit.C->log()->elem("dynamic_call bci='%d'", jvms->bci()); C->log()->elem("dynamic_call bci='%d'", jvms->bci());
} }
// Get the constant pool cache from the caller class. // Get the constant pool cache from the caller class.
...@@ -190,18 +192,21 @@ JVMState* DynamicCallGenerator::generate(JVMState* jvms) { ...@@ -190,18 +192,21 @@ JVMState* DynamicCallGenerator::generate(JVMState* jvms) {
size_t call_site_offset = cpcache->get_f1_offset(index); size_t call_site_offset = cpcache->get_f1_offset(index);
// Load the CallSite object from the constant pool cache. // Load the CallSite object from the constant pool cache.
const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache); const TypeOopPtr* cpcache_type = TypeOopPtr::make_from_constant(cpcache); // returns TypeAryPtr of type T_OBJECT
Node* cpcache_adr = kit.makecon(cpcache_ptr); const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass());
Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset); Node* cpcache_adr = kit.makecon(cpcache_type);
Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw); Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, call_site_offset);
// The oops in the constant pool cache are not compressed; load then as raw pointers.
Node* call_site = kit.make_load(kit.control(), call_site_adr, call_site_type, T_ADDRESS, Compile::AliasIdxRaw);
// Load the target MethodHandle from the CallSite object. // Load the target MethodHandle from the CallSite object.
Node* target_mh_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes()); const TypeOopPtr* target_type = TypeOopPtr::make_from_klass(C->env()->MethodHandle_klass());
Node* target_mh = kit.make_load(kit.control(), target_mh_adr, TypeInstPtr::BOTTOM, T_OBJECT); Node* target_mh_adr = kit.basic_plus_adr(call_site, java_lang_invoke_CallSite::target_offset_in_bytes());
Node* target_mh = kit.make_load(kit.control(), target_mh_adr, target_type, T_OBJECT);
address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub(); address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub();
CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci()); CallStaticJavaNode* call = new (C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci());
// invokedynamic is treated as an optimized invokevirtual. // invokedynamic is treated as an optimized invokevirtual.
call->set_optimized_virtual(true); call->set_optimized_virtual(true);
// Take extra care (in the presence of argument motion) not to trash the SP: // Take extra care (in the presence of argument motion) not to trash the SP:
...@@ -785,9 +790,10 @@ CallGenerator* CallGenerator::for_invokedynamic_inline(ciCallSite* call_site, JV ...@@ -785,9 +790,10 @@ CallGenerator* CallGenerator::for_invokedynamic_inline(ciCallSite* call_site, JV
JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) { JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
GraphKit kit(jvms); GraphKit kit(jvms);
Compile* C = kit.C;
PhaseGVN& gvn = kit.gvn(); PhaseGVN& gvn = kit.gvn();
CompileLog* log = kit.C->log(); CompileLog* log = C->log();
if (log != NULL) { if (log != NULL) {
log->elem("predicted_dynamic_call bci='%d'", jvms->bci()); log->elem("predicted_dynamic_call bci='%d'", jvms->bci());
} }
...@@ -803,8 +809,8 @@ JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) { ...@@ -803,8 +809,8 @@ JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
Node* receiver = kit.argument(0); Node* receiver = kit.argument(0);
// Check if the MethodHandle is the expected one // Check if the MethodHandle is the expected one
Node* cmp = gvn.transform(new(kit.C, 3) CmpPNode(receiver, predicted_mh)); Node* cmp = gvn.transform(new (C, 3) CmpPNode(receiver, predicted_mh));
bol = gvn.transform(new(kit.C, 2) BoolNode(cmp, BoolTest::eq) ); bol = gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq) );
} else { } else {
// Get the constant pool cache from the caller class. // Get the constant pool cache from the caller class.
ciMethod* caller_method = jvms->method(); ciMethod* caller_method = jvms->method();
...@@ -818,22 +824,25 @@ JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) { ...@@ -818,22 +824,25 @@ JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
size_t call_site_offset = cpcache->get_f1_offset(index); size_t call_site_offset = cpcache->get_f1_offset(index);
// Load the CallSite object from the constant pool cache. // Load the CallSite object from the constant pool cache.
const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache); const TypeOopPtr* cpcache_type = TypeOopPtr::make_from_constant(cpcache); // returns TypeAryPtr of type T_OBJECT
Node* cpcache_adr = kit.makecon(cpcache_ptr); const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass());
Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset); Node* cpcache_adr = kit.makecon(cpcache_type);
Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw); Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, call_site_offset);
// The oops in the constant pool cache are not compressed; load then as raw pointers.
Node* call_site = kit.make_load(kit.control(), call_site_adr, call_site_type, T_ADDRESS, Compile::AliasIdxRaw);
// Load the target MethodHandle from the CallSite object. // Load the target MethodHandle from the CallSite object.
const TypeOopPtr* target_type = TypeOopPtr::make_from_klass(C->env()->MethodHandle_klass());
Node* target_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes()); Node* target_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes());
Node* target_mh = kit.make_load(kit.control(), target_adr, TypeInstPtr::BOTTOM, T_OBJECT); Node* target_mh = kit.make_load(kit.control(), target_adr, target_type, T_OBJECT);
// Check if the MethodHandle is still the same. // Check if the MethodHandle is still the same.
Node* cmp = gvn.transform(new(kit.C, 3) CmpPNode(target_mh, predicted_mh)); Node* cmp = gvn.transform(new (C, 3) CmpPNode(target_mh, predicted_mh));
bol = gvn.transform(new(kit.C, 2) BoolNode(cmp, BoolTest::eq) ); bol = gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq) );
} }
IfNode* iff = kit.create_and_xform_if(kit.control(), bol, _hit_prob, COUNT_UNKNOWN); IfNode* iff = kit.create_and_xform_if(kit.control(), bol, _hit_prob, COUNT_UNKNOWN);
kit.set_control( gvn.transform(new(kit.C, 1) IfTrueNode (iff))); kit.set_control( gvn.transform(new (C, 1) IfTrueNode (iff)));
Node* slow_ctl = gvn.transform(new(kit.C, 1) IfFalseNode(iff)); Node* slow_ctl = gvn.transform(new (C, 1) IfFalseNode(iff));
SafePointNode* slow_map = NULL; SafePointNode* slow_map = NULL;
JVMState* slow_jvms; JVMState* slow_jvms;
...@@ -882,7 +891,7 @@ JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) { ...@@ -882,7 +891,7 @@ JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
// Finish the diamond. // Finish the diamond.
kit.C->set_has_split_ifs(true); // Has chance for split-if optimization kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
RegionNode* region = new (kit.C, 3) RegionNode(3); RegionNode* region = new (C, 3) RegionNode(3);
region->init_req(1, kit.control()); region->init_req(1, kit.control());
region->init_req(2, slow_map->control()); region->init_req(2, slow_map->control());
kit.set_control(gvn.transform(region)); kit.set_control(gvn.transform(region));
......
...@@ -1536,7 +1536,7 @@ Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derive ...@@ -1536,7 +1536,7 @@ Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derive
// Check for AddP-related opcodes // Check for AddP-related opcodes
if( !derived->is_Phi() ) { if( !derived->is_Phi() ) {
assert( derived->as_Mach()->ideal_Opcode() == Op_AddP, "" ); assert(derived->as_Mach()->ideal_Opcode() == Op_AddP, err_msg("but is: %s", derived->Name()));
Node *base = derived->in(AddPNode::Base); Node *base = derived->in(AddPNode::Base);
derived_base_map[derived->_idx] = base; derived_base_map[derived->_idx] = base;
return base; return base;
......
...@@ -2613,18 +2613,26 @@ const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass *klass, bool klass_ ...@@ -2613,18 +2613,26 @@ const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass *klass, bool klass_
//------------------------------make_from_constant----------------------------- //------------------------------make_from_constant-----------------------------
// Make a java pointer from an oop constant // Make a java pointer from an oop constant
const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_constant) { const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_constant) {
if (o->is_method_data() || o->is_method() || o->is_cpcache()) { if (o->is_method_data() || o->is_method()) {
// Treat much like a typeArray of bytes, like below, but fake the type... // Treat much like a typeArray of bytes, like below, but fake the type...
const Type* etype = (Type*)get_const_basic_type(T_BYTE); const BasicType bt = T_BYTE;
const Type* etype = get_const_basic_type(bt);
const TypeAry* arr0 = TypeAry::make(etype, TypeInt::POS); const TypeAry* arr0 = TypeAry::make(etype, TypeInt::POS);
ciKlass *klass = ciTypeArrayKlass::make((BasicType) T_BYTE); ciKlass* klass = ciArrayKlass::make(ciType::make(bt));
assert(o->can_be_constant(), "method data oops should be tenured"); assert(o->can_be_constant(), "should be tenured");
const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0); return TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
return arr; } else if (o->is_cpcache()) {
// Treat much like a objArray, like below, but fake the type...
const BasicType bt = T_OBJECT;
const Type* etype = get_const_basic_type(bt);
const TypeAry* arr0 = TypeAry::make(etype, TypeInt::POS);
ciKlass* klass = ciArrayKlass::make(ciType::make(bt));
assert(o->can_be_constant(), "should be tenured");
return TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
} else { } else {
assert(o->is_java_object(), "must be java language object"); assert(o->is_java_object(), "must be java language object");
assert(!o->is_null_object(), "null object not yet handled here."); assert(!o->is_null_object(), "null object not yet handled here.");
ciKlass *klass = o->klass(); ciKlass* klass = o->klass();
if (klass->is_instance_klass()) { if (klass->is_instance_klass()) {
// Element is an instance // Element is an instance
if (require_constant) { if (require_constant) {
...@@ -2635,8 +2643,7 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const ...@@ -2635,8 +2643,7 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const
return TypeInstPtr::make(o); return TypeInstPtr::make(o);
} else if (klass->is_obj_array_klass()) { } else if (klass->is_obj_array_klass()) {
// Element is an object array. Recursively call ourself. // Element is an object array. Recursively call ourself.
const Type *etype = const Type *etype = make_from_klass_raw(klass->as_obj_array_klass()->element_klass());
TypeOopPtr::make_from_klass_raw(klass->as_obj_array_klass()->element_klass());
const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length())); const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
// We used to pass NotNull in here, asserting that the sub-arrays // We used to pass NotNull in here, asserting that the sub-arrays
// are all not-null. This is not true in generally, as code can // are all not-null. This is not true in generally, as code can
...@@ -2646,12 +2653,10 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const ...@@ -2646,12 +2653,10 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const
} else if (!o->should_be_constant()) { } else if (!o->should_be_constant()) {
return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0); return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
} }
const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0); return TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
return arr;
} else if (klass->is_type_array_klass()) { } else if (klass->is_type_array_klass()) {
// Element is an typeArray // Element is an typeArray
const Type* etype = const Type* etype = get_const_basic_type(klass->as_type_array_klass()->element_type());
(Type*)get_const_basic_type(klass->as_type_array_klass()->element_type());
const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length())); const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
// We used to pass NotNull in here, asserting that the array pointer // We used to pass NotNull in here, asserting that the array pointer
// is not-null. That was not true in general. // is not-null. That was not true in general.
...@@ -2660,12 +2665,11 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const ...@@ -2660,12 +2665,11 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const
} else if (!o->should_be_constant()) { } else if (!o->should_be_constant()) {
return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0); return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
} }
const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0); return TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
return arr;
} }
} }
ShouldNotReachHere(); fatal("unhandled object type");
return NULL; return NULL;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册