提交 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 {
}
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");
return _typeArrayKlassObjs[t];
}
......
......@@ -172,9 +172,11 @@ public:
JVMState* DynamicCallGenerator::generate(JVMState* jvms) {
GraphKit kit(jvms);
Compile* C = kit.C;
PhaseGVN& gvn = kit.gvn();
if (kit.C->log() != NULL) {
kit.C->log()->elem("dynamic_call bci='%d'", jvms->bci());
if (C->log() != NULL) {
C->log()->elem("dynamic_call bci='%d'", jvms->bci());
}
// Get the constant pool cache from the caller class.
......@@ -190,18 +192,21 @@ JVMState* DynamicCallGenerator::generate(JVMState* jvms) {
size_t call_site_offset = cpcache->get_f1_offset(index);
// Load the CallSite object from the constant pool cache.
const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache);
Node* cpcache_adr = kit.makecon(cpcache_ptr);
Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset);
Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw);
const TypeOopPtr* cpcache_type = TypeOopPtr::make_from_constant(cpcache); // returns TypeAryPtr of type T_OBJECT
const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass());
Node* cpcache_adr = kit.makecon(cpcache_type);
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.
Node* target_mh_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_mh_adr, TypeInstPtr::BOTTOM, T_OBJECT);
const TypeOopPtr* target_type = TypeOopPtr::make_from_klass(C->env()->MethodHandle_klass());
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();
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.
call->set_optimized_virtual(true);
// 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
JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
GraphKit kit(jvms);
Compile* C = kit.C;
PhaseGVN& gvn = kit.gvn();
CompileLog* log = kit.C->log();
CompileLog* log = C->log();
if (log != NULL) {
log->elem("predicted_dynamic_call bci='%d'", jvms->bci());
}
......@@ -803,8 +809,8 @@ JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
Node* receiver = kit.argument(0);
// Check if the MethodHandle is the expected one
Node* cmp = gvn.transform(new(kit.C, 3) CmpPNode(receiver, predicted_mh));
bol = gvn.transform(new(kit.C, 2) BoolNode(cmp, BoolTest::eq) );
Node* cmp = gvn.transform(new (C, 3) CmpPNode(receiver, predicted_mh));
bol = gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq) );
} else {
// Get the constant pool cache from the caller class.
ciMethod* caller_method = jvms->method();
......@@ -818,22 +824,25 @@ JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
size_t call_site_offset = cpcache->get_f1_offset(index);
// Load the CallSite object from the constant pool cache.
const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache);
Node* cpcache_adr = kit.makecon(cpcache_ptr);
Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset);
Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw);
const TypeOopPtr* cpcache_type = TypeOopPtr::make_from_constant(cpcache); // returns TypeAryPtr of type T_OBJECT
const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass());
Node* cpcache_adr = kit.makecon(cpcache_type);
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.
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_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.
Node* cmp = gvn.transform(new(kit.C, 3) CmpPNode(target_mh, predicted_mh));
bol = gvn.transform(new(kit.C, 2) BoolNode(cmp, BoolTest::eq) );
Node* cmp = gvn.transform(new (C, 3) CmpPNode(target_mh, predicted_mh));
bol = gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq) );
}
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)));
Node* slow_ctl = gvn.transform(new(kit.C, 1) IfFalseNode(iff));
kit.set_control( gvn.transform(new (C, 1) IfTrueNode (iff)));
Node* slow_ctl = gvn.transform(new (C, 1) IfFalseNode(iff));
SafePointNode* slow_map = NULL;
JVMState* slow_jvms;
......@@ -882,7 +891,7 @@ JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
// Finish the diamond.
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(2, slow_map->control());
kit.set_control(gvn.transform(region));
......
......@@ -1536,7 +1536,7 @@ Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derive
// Check for AddP-related opcodes
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);
derived_base_map[derived->_idx] = base;
return base;
......
......@@ -2613,18 +2613,26 @@ const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass *klass, bool klass_
//------------------------------make_from_constant-----------------------------
// Make a java pointer from an oop 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...
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);
ciKlass *klass = ciTypeArrayKlass::make((BasicType) T_BYTE);
assert(o->can_be_constant(), "method data oops should be tenured");
const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
return arr;
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 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 {
assert(o->is_java_object(), "must be java language object");
assert(!o->is_null_object(), "null object not yet handled here.");
ciKlass *klass = o->klass();
ciKlass* klass = o->klass();
if (klass->is_instance_klass()) {
// Element is an instance
if (require_constant) {
......@@ -2635,8 +2643,7 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const
return TypeInstPtr::make(o);
} else if (klass->is_obj_array_klass()) {
// Element is an object array. Recursively call ourself.
const Type *etype =
TypeOopPtr::make_from_klass_raw(klass->as_obj_array_klass()->element_klass());
const Type *etype = make_from_klass_raw(klass->as_obj_array_klass()->element_klass());
const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
// 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
......@@ -2646,12 +2653,10 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const
} else if (!o->should_be_constant()) {
return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
}
const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
return arr;
return TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
} else if (klass->is_type_array_klass()) {
// Element is an typeArray
const Type* etype =
(Type*)get_const_basic_type(klass->as_type_array_klass()->element_type());
const Type* etype = get_const_basic_type(klass->as_type_array_klass()->element_type());
const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
// We used to pass NotNull in here, asserting that the array pointer
// is not-null. That was not true in general.
......@@ -2660,12 +2665,11 @@ const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_const
} else if (!o->should_be_constant()) {
return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
}
const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
return arr;
return TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
}
}
ShouldNotReachHere();
fatal("unhandled object type");
return NULL;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册