7157365: jruby/bench.bench_timeout crashes with JVM internal error
Reviewed-by: jrose, kvn
--- a/hotspot/src/share/vm/memory/universe.hpp Mon Jun 18 12:29:21 2012 -0700
+++ b/hotspot/src/share/vm/memory/universe.hpp Mon Jun 18 15:17:30 2012 -0700
@@ -273,7 +273,7 @@
}
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];
}
--- a/hotspot/src/share/vm/opto/callGenerator.cpp Mon Jun 18 12:29:21 2012 -0700
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp Mon Jun 18 15:17:30 2012 -0700
@@ -172,9 +172,11 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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));
--- a/hotspot/src/share/vm/opto/chaitin.cpp Mon Jun 18 12:29:21 2012 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.cpp Mon Jun 18 15:17:30 2012 -0700
@@ -1536,7 +1536,7 @@
// 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;
--- a/hotspot/src/share/vm/opto/type.cpp Mon Jun 18 12:29:21 2012 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp Mon Jun 18 15:17:30 2012 -0700
@@ -2613,18 +2613,26 @@
//------------------------------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 @@
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 @@
} 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 @@
} 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;
}