mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 17:44:40 +02:00
8266550: C2: mirror TypeOopPtr/TypeInstPtr/TypeAryPtr with TypeKlassPtr/TypeInstKlassPtr/TypeAryKlassPtr
Reviewed-by: vlivanov, thartmann
This commit is contained in:
parent
a143372818
commit
1d2458db34
18 changed files with 992 additions and 457 deletions
|
@ -88,14 +88,14 @@ ArrayKlass::ArrayKlass(Symbol* name, KlassID id) :
|
||||||
_dimension(1),
|
_dimension(1),
|
||||||
_higher_dimension(NULL),
|
_higher_dimension(NULL),
|
||||||
_lower_dimension(NULL) {
|
_lower_dimension(NULL) {
|
||||||
// Arrays don't add any new methods, so their vtable is the same size as
|
// Arrays don't add any new methods, so their vtable is the same size as
|
||||||
// the vtable of klass Object.
|
// the vtable of klass Object.
|
||||||
set_vtable_length(Universe::base_vtable_size());
|
set_vtable_length(Universe::base_vtable_size());
|
||||||
set_name(name);
|
set_name(name);
|
||||||
set_super(Universe::is_bootstrapping() ? NULL : vmClasses::Object_klass());
|
set_super(Universe::is_bootstrapping() ? NULL : vmClasses::Object_klass());
|
||||||
set_layout_helper(Klass::_lh_neutral_value);
|
set_layout_helper(Klass::_lh_neutral_value);
|
||||||
set_is_cloneable(); // All arrays are considered to be cloneable (See JLS 20.1.5)
|
set_is_cloneable(); // All arrays are considered to be cloneable (See JLS 20.1.5)
|
||||||
JFR_ONLY(INIT_ID(this);)
|
JFR_ONLY(INIT_ID(this);)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -378,6 +378,8 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c
|
||||||
st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->isa_oopptr()->const_oop()));
|
st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->isa_oopptr()->const_oop()));
|
||||||
break;
|
break;
|
||||||
case Type::KlassPtr:
|
case Type::KlassPtr:
|
||||||
|
case Type::AryKlassPtr:
|
||||||
|
case Type::InstKlassPtr:
|
||||||
st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->make_ptr()->isa_klassptr()->klass()));
|
st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->make_ptr()->isa_klassptr()->klass()));
|
||||||
break;
|
break;
|
||||||
case Type::MetadataPtr:
|
case Type::MetadataPtr:
|
||||||
|
|
|
@ -1140,7 +1140,7 @@ const Type* PhiNode::Value(PhaseGVN* phase) const {
|
||||||
// convert the one to the other.
|
// convert the one to the other.
|
||||||
const TypePtr* ttp = _type->make_ptr();
|
const TypePtr* ttp = _type->make_ptr();
|
||||||
const TypeInstPtr* ttip = (ttp != NULL) ? ttp->isa_instptr() : NULL;
|
const TypeInstPtr* ttip = (ttp != NULL) ? ttp->isa_instptr() : NULL;
|
||||||
const TypeKlassPtr* ttkp = (ttp != NULL) ? ttp->isa_klassptr() : NULL;
|
const TypeKlassPtr* ttkp = (ttp != NULL) ? ttp->isa_instklassptr() : NULL;
|
||||||
bool is_intf = false;
|
bool is_intf = false;
|
||||||
if (ttip != NULL) {
|
if (ttip != NULL) {
|
||||||
ciKlass* k = ttip->klass();
|
ciKlass* k = ttip->klass();
|
||||||
|
@ -1233,7 +1233,7 @@ const Type* PhiNode::Value(PhaseGVN* phase) const {
|
||||||
// because the type system doesn't interact well with interfaces.
|
// because the type system doesn't interact well with interfaces.
|
||||||
const TypePtr *jtp = jt->make_ptr();
|
const TypePtr *jtp = jt->make_ptr();
|
||||||
const TypeInstPtr *jtip = (jtp != NULL) ? jtp->isa_instptr() : NULL;
|
const TypeInstPtr *jtip = (jtp != NULL) ? jtp->isa_instptr() : NULL;
|
||||||
const TypeKlassPtr *jtkp = (jtp != NULL) ? jtp->isa_klassptr() : NULL;
|
const TypeKlassPtr *jtkp = (jtp != NULL) ? jtp->isa_instklassptr() : NULL;
|
||||||
if( jtip && ttip ) {
|
if( jtip && ttip ) {
|
||||||
if( jtip->is_loaded() && jtip->klass()->is_interface() &&
|
if( jtip->is_loaded() && jtip->klass()->is_interface() &&
|
||||||
ttip->is_loaded() && !ttip->klass()->is_interface() ) {
|
ttip->is_loaded() && !ttip->klass()->is_interface() ) {
|
||||||
|
|
|
@ -1410,7 +1410,7 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
|
||||||
if ( offset == Type::OffsetBot || (offset >= 0 && (size_t)offset < sizeof(Klass)) ) {
|
if ( offset == Type::OffsetBot || (offset >= 0 && (size_t)offset < sizeof(Klass)) ) {
|
||||||
|
|
||||||
tj = tk = TypeKlassPtr::make(TypePtr::NotNull,
|
tj = tk = TypeKlassPtr::make(TypePtr::NotNull,
|
||||||
TypeKlassPtr::OBJECT->klass(),
|
TypeInstKlassPtr::OBJECT->klass(),
|
||||||
offset);
|
offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1457,7 +1457,9 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
|
||||||
case Type::RawPtr: tj = TypeRawPtr::BOTTOM; break;
|
case Type::RawPtr: tj = TypeRawPtr::BOTTOM; break;
|
||||||
case Type::AryPtr: // do not distinguish arrays at all
|
case Type::AryPtr: // do not distinguish arrays at all
|
||||||
case Type::InstPtr: tj = TypeInstPtr::BOTTOM; break;
|
case Type::InstPtr: tj = TypeInstPtr::BOTTOM; break;
|
||||||
case Type::KlassPtr: tj = TypeKlassPtr::OBJECT; break;
|
case Type::KlassPtr:
|
||||||
|
case Type::AryKlassPtr:
|
||||||
|
case Type::InstKlassPtr: tj = TypeInstKlassPtr::OBJECT; break;
|
||||||
case Type::AnyPtr: tj = TypePtr::BOTTOM; break; // caller checks it
|
case Type::AnyPtr: tj = TypePtr::BOTTOM; break; // caller checks it
|
||||||
default: ShouldNotReachHere();
|
default: ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
|
@ -916,7 +916,7 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
|
||||||
Node* ex_klass_node = NULL;
|
Node* ex_klass_node = NULL;
|
||||||
if (has_ex_handler() && !ex_type->klass_is_exact()) {
|
if (has_ex_handler() && !ex_type->klass_is_exact()) {
|
||||||
Node* p = basic_plus_adr( ex_node, ex_node, oopDesc::klass_offset_in_bytes());
|
Node* p = basic_plus_adr( ex_node, ex_node, oopDesc::klass_offset_in_bytes());
|
||||||
ex_klass_node = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT));
|
ex_klass_node = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS, TypeInstKlassPtr::OBJECT));
|
||||||
|
|
||||||
// Compute the exception klass a little more cleverly.
|
// Compute the exception klass a little more cleverly.
|
||||||
// Obvious solution is to simple do a LoadKlass from the 'ex_node'.
|
// Obvious solution is to simple do a LoadKlass from the 'ex_node'.
|
||||||
|
@ -925,7 +925,7 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
|
||||||
// I'm loading the class from, I can replace the LoadKlass with the
|
// I'm loading the class from, I can replace the LoadKlass with the
|
||||||
// klass constant for the exception oop.
|
// klass constant for the exception oop.
|
||||||
if (ex_node->is_Phi()) {
|
if (ex_node->is_Phi()) {
|
||||||
ex_klass_node = new PhiNode(ex_node->in(0), TypeKlassPtr::OBJECT);
|
ex_klass_node = new PhiNode(ex_node->in(0), TypeInstKlassPtr::OBJECT);
|
||||||
for (uint i = 1; i < ex_node->req(); i++) {
|
for (uint i = 1; i < ex_node->req(); i++) {
|
||||||
Node* ex_in = ex_node->in(i);
|
Node* ex_in = ex_node->in(i);
|
||||||
if (ex_in == top() || ex_in == NULL) {
|
if (ex_in == top() || ex_in == NULL) {
|
||||||
|
@ -934,10 +934,10 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Node* p = basic_plus_adr(ex_in, ex_in, oopDesc::klass_offset_in_bytes());
|
Node* p = basic_plus_adr(ex_in, ex_in, oopDesc::klass_offset_in_bytes());
|
||||||
Node* k = _gvn.transform( LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT));
|
Node* k = _gvn.transform( LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS, TypeInstKlassPtr::OBJECT));
|
||||||
ex_klass_node->init_req( i, k );
|
ex_klass_node->init_req( i, k );
|
||||||
}
|
}
|
||||||
_gvn.set_type(ex_klass_node, TypeKlassPtr::OBJECT);
|
_gvn.set_type(ex_klass_node, TypeInstKlassPtr::OBJECT);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3117,7 +3117,7 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist,
|
||||||
// to the actual Array type.
|
// to the actual Array type.
|
||||||
if (alloc->is_Allocate() && n->as_Type()->type() == TypeInstPtr::NOTNULL
|
if (alloc->is_Allocate() && n->as_Type()->type() == TypeInstPtr::NOTNULL
|
||||||
&& (alloc->is_AllocateArray() ||
|
&& (alloc->is_AllocateArray() ||
|
||||||
igvn->type(alloc->in(AllocateNode::KlassNode)) != TypeKlassPtr::OBJECT)) {
|
igvn->type(alloc->in(AllocateNode::KlassNode)) != TypeInstKlassPtr::OBJECT)) {
|
||||||
Node *cast2 = NULL;
|
Node *cast2 = NULL;
|
||||||
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
|
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
|
||||||
Node *use = n->fast_out(i);
|
Node *use = n->fast_out(i);
|
||||||
|
|
|
@ -2867,7 +2867,7 @@ Node* Phase::gen_subtype_check(Node* subklass, Node* superklass, Node** ctrl, No
|
||||||
if (might_be_cache && mem != NULL) {
|
if (might_be_cache && mem != NULL) {
|
||||||
kmem = mem->is_MergeMem() ? mem->as_MergeMem()->memory_at(C->get_alias_index(gvn.type(p2)->is_ptr())) : mem;
|
kmem = mem->is_MergeMem() ? mem->as_MergeMem()->memory_at(C->get_alias_index(gvn.type(p2)->is_ptr())) : mem;
|
||||||
}
|
}
|
||||||
Node *nkls = gvn.transform(LoadKlassNode::make(gvn, NULL, kmem, p2, gvn.type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL));
|
Node *nkls = gvn.transform(LoadKlassNode::make(gvn, NULL, kmem, p2, gvn.type(p2)->is_ptr(), TypeInstKlassPtr::OBJECT_OR_NULL));
|
||||||
|
|
||||||
// Compile speed common case: ARE a subtype and we canNOT fail
|
// Compile speed common case: ARE a subtype and we canNOT fail
|
||||||
if( superklass == nkls )
|
if( superklass == nkls )
|
||||||
|
@ -3798,7 +3798,7 @@ Node* GraphKit::new_instance(Node* klass_node,
|
||||||
// (Actually, it need not be precise if this is a reflective allocation.)
|
// (Actually, it need not be precise if this is a reflective allocation.)
|
||||||
// It's what we cast the result to.
|
// It's what we cast the result to.
|
||||||
const TypeKlassPtr* tklass = _gvn.type(klass_node)->isa_klassptr();
|
const TypeKlassPtr* tklass = _gvn.type(klass_node)->isa_klassptr();
|
||||||
if (!tklass) tklass = TypeKlassPtr::OBJECT;
|
if (!tklass) tklass = TypeInstKlassPtr::OBJECT;
|
||||||
const TypeOopPtr* oop_type = tklass->as_instance_type();
|
const TypeOopPtr* oop_type = tklass->as_instance_type();
|
||||||
|
|
||||||
// Now generate allocation code
|
// Now generate allocation code
|
||||||
|
|
|
@ -545,7 +545,7 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
|
||||||
} else {
|
} else {
|
||||||
print_prop(short_name, "L");
|
print_prop(short_name, "L");
|
||||||
}
|
}
|
||||||
} else if (t->base() == Type::KlassPtr) {
|
} else if (t->base() == Type::KlassPtr || t->base() == Type::InstKlassPtr || t->base() == Type::AryKlassPtr) {
|
||||||
const TypeKlassPtr *typeKlass = t->is_klassptr();
|
const TypeKlassPtr *typeKlass = t->is_klassptr();
|
||||||
print_prop(short_name, "CP");
|
print_prop(short_name, "CP");
|
||||||
} else if (t->base() == Type::Control) {
|
} else if (t->base() == Type::Control) {
|
||||||
|
|
|
@ -2838,7 +2838,7 @@ bool LibraryCallKit::inline_native_classID() {
|
||||||
IdealVariable result(ideal); __ declarations_done();
|
IdealVariable result(ideal); __ declarations_done();
|
||||||
Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(),
|
Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(),
|
||||||
basic_plus_adr(cls, java_lang_Class::klass_offset()),
|
basic_plus_adr(cls, java_lang_Class::klass_offset()),
|
||||||
TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL));
|
TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL));
|
||||||
|
|
||||||
|
|
||||||
__ if_then(kls, BoolTest::ne, null()); {
|
__ if_then(kls, BoolTest::ne, null()); {
|
||||||
|
@ -2868,7 +2868,7 @@ bool LibraryCallKit::inline_native_classID() {
|
||||||
} __ else_(); {
|
} __ else_(); {
|
||||||
Node* array_kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(),
|
Node* array_kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(),
|
||||||
basic_plus_adr(cls, java_lang_Class::array_klass_offset()),
|
basic_plus_adr(cls, java_lang_Class::array_klass_offset()),
|
||||||
TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL));
|
TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL));
|
||||||
__ if_then(array_kls, BoolTest::ne, null()); {
|
__ if_then(array_kls, BoolTest::ne, null()); {
|
||||||
Node* array_kls_trace_id_addr = basic_plus_adr(array_kls, in_bytes(KLASS_TRACE_ID_OFFSET));
|
Node* array_kls_trace_id_addr = basic_plus_adr(array_kls, in_bytes(KLASS_TRACE_ID_OFFSET));
|
||||||
Node* array_kls_trace_id_raw = ideal.load(ideal.ctrl(), array_kls_trace_id_addr, TypeLong::LONG, T_LONG, Compile::AliasIdxRaw);
|
Node* array_kls_trace_id_raw = ideal.load(ideal.ctrl(), array_kls_trace_id_addr, TypeLong::LONG, T_LONG, Compile::AliasIdxRaw);
|
||||||
|
@ -2961,7 +2961,7 @@ Node* LibraryCallKit::load_klass_from_mirror_common(Node* mirror,
|
||||||
int offset) {
|
int offset) {
|
||||||
if (region == NULL) never_see_null = true;
|
if (region == NULL) never_see_null = true;
|
||||||
Node* p = basic_plus_adr(mirror, offset);
|
Node* p = basic_plus_adr(mirror, offset);
|
||||||
const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL;
|
const TypeKlassPtr* kls_type = TypeInstKlassPtr::OBJECT_OR_NULL;
|
||||||
Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type));
|
Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type));
|
||||||
Node* null_ctl = top();
|
Node* null_ctl = top();
|
||||||
kls = null_check_oop(kls, &null_ctl, never_see_null);
|
kls = null_check_oop(kls, &null_ctl, never_see_null);
|
||||||
|
@ -3150,7 +3150,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) {
|
||||||
phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror())));
|
phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror())));
|
||||||
// If we fall through, it's a plain class. Get its _super.
|
// If we fall through, it's a plain class. Get its _super.
|
||||||
p = basic_plus_adr(kls, in_bytes(Klass::super_offset()));
|
p = basic_plus_adr(kls, in_bytes(Klass::super_offset()));
|
||||||
kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL));
|
kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL));
|
||||||
null_ctl = top();
|
null_ctl = top();
|
||||||
kls = null_check_oop(kls, &null_ctl);
|
kls = null_check_oop(kls, &null_ctl);
|
||||||
if (null_ctl != top()) {
|
if (null_ctl != top()) {
|
||||||
|
@ -3292,7 +3292,7 @@ bool LibraryCallKit::inline_native_subtype_check() {
|
||||||
record_for_igvn(region);
|
record_for_igvn(region);
|
||||||
|
|
||||||
const TypePtr* adr_type = TypeRawPtr::BOTTOM; // memory type of loads
|
const TypePtr* adr_type = TypeRawPtr::BOTTOM; // memory type of loads
|
||||||
const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL;
|
const TypeKlassPtr* kls_type = TypeInstKlassPtr::OBJECT_OR_NULL;
|
||||||
int class_klass_offset = java_lang_Class::klass_offset();
|
int class_klass_offset = java_lang_Class::klass_offset();
|
||||||
|
|
||||||
// First null-check both mirrors and load each mirror's klass metaobject.
|
// First null-check both mirrors and load each mirror's klass metaobject.
|
||||||
|
@ -6004,7 +6004,7 @@ bool LibraryCallKit::inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id) {
|
||||||
|
|
||||||
ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
|
ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
|
||||||
const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt);
|
const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt);
|
||||||
const TypeOopPtr* xtype = aklass->as_instance_type();
|
const TypeOopPtr* xtype = aklass->as_instance_type()->cast_to_ptr_type(TypePtr::NotNull);
|
||||||
Node* aescrypt_object = new CheckCastPPNode(control(), embeddedCipherObj, xtype);
|
Node* aescrypt_object = new CheckCastPPNode(control(), embeddedCipherObj, xtype);
|
||||||
aescrypt_object = _gvn.transform(aescrypt_object);
|
aescrypt_object = _gvn.transform(aescrypt_object);
|
||||||
|
|
||||||
|
@ -6092,7 +6092,7 @@ bool LibraryCallKit::inline_electronicCodeBook_AESCrypt(vmIntrinsics::ID id) {
|
||||||
|
|
||||||
ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
|
ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
|
||||||
const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt);
|
const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt);
|
||||||
const TypeOopPtr* xtype = aklass->as_instance_type();
|
const TypeOopPtr* xtype = aklass->as_instance_type()->cast_to_ptr_type(TypePtr::NotNull);
|
||||||
Node* aescrypt_object = new CheckCastPPNode(control(), embeddedCipherObj, xtype);
|
Node* aescrypt_object = new CheckCastPPNode(control(), embeddedCipherObj, xtype);
|
||||||
aescrypt_object = _gvn.transform(aescrypt_object);
|
aescrypt_object = _gvn.transform(aescrypt_object);
|
||||||
|
|
||||||
|
@ -6163,7 +6163,7 @@ bool LibraryCallKit::inline_counterMode_AESCrypt(vmIntrinsics::ID id) {
|
||||||
assert(klass_AESCrypt->is_loaded(), "predicate checks that this class is loaded");
|
assert(klass_AESCrypt->is_loaded(), "predicate checks that this class is loaded");
|
||||||
ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
|
ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
|
||||||
const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt);
|
const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt);
|
||||||
const TypeOopPtr* xtype = aklass->as_instance_type();
|
const TypeOopPtr* xtype = aklass->as_instance_type()->cast_to_ptr_type(TypePtr::NotNull);
|
||||||
Node* aescrypt_object = new CheckCastPPNode(control(), embeddedCipherObj, xtype);
|
Node* aescrypt_object = new CheckCastPPNode(control(), embeddedCipherObj, xtype);
|
||||||
aescrypt_object = _gvn.transform(aescrypt_object);
|
aescrypt_object = _gvn.transform(aescrypt_object);
|
||||||
// we need to get the start of the aescrypt_object's expanded key array
|
// we need to get the start of the aescrypt_object's expanded key array
|
||||||
|
@ -6681,7 +6681,7 @@ bool LibraryCallKit::inline_digestBase_implCompressMB(Node* digestBase_obj, ciIn
|
||||||
const char* state_type, address stubAddr, const char *stubName,
|
const char* state_type, address stubAddr, const char *stubName,
|
||||||
Node* src_start, Node* ofs, Node* limit) {
|
Node* src_start, Node* ofs, Node* limit) {
|
||||||
const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_digestBase);
|
const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_digestBase);
|
||||||
const TypeOopPtr* xtype = aklass->as_instance_type();
|
const TypeOopPtr* xtype = aklass->as_instance_type()->cast_to_ptr_type(TypePtr::NotNull);
|
||||||
Node* digest_obj = new CheckCastPPNode(control(), digestBase_obj, xtype);
|
Node* digest_obj = new CheckCastPPNode(control(), digestBase_obj, xtype);
|
||||||
digest_obj = _gvn.transform(digest_obj);
|
digest_obj = _gvn.transform(digest_obj);
|
||||||
|
|
||||||
|
|
|
@ -1972,7 +1972,7 @@ const Type* LoadNode::Value(PhaseGVN* phase) const {
|
||||||
return con_type;
|
return con_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (tp->base() == Type::KlassPtr) {
|
} else if (tp->base() == Type::KlassPtr || tp->base() == Type::InstKlassPtr || tp->base() == Type::AryKlassPtr) {
|
||||||
assert( off != Type::OffsetBot ||
|
assert( off != Type::OffsetBot ||
|
||||||
// arrays can be cast to Objects
|
// arrays can be cast to Objects
|
||||||
tp->is_klassptr()->klass()->is_java_lang_Object() ||
|
tp->is_klassptr()->klass()->is_java_lang_Object() ||
|
||||||
|
|
|
@ -528,7 +528,7 @@ public:
|
||||||
|
|
||||||
// Polymorphic factory method:
|
// Polymorphic factory method:
|
||||||
static Node* make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at,
|
static Node* make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at,
|
||||||
const TypeKlassPtr* tk = TypeKlassPtr::OBJECT);
|
const TypeKlassPtr* tk = TypeInstKlassPtr::OBJECT);
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------LoadNKlassNode---------------------------------
|
//------------------------------LoadNKlassNode---------------------------------
|
||||||
|
|
|
@ -168,7 +168,7 @@ void Parse::array_store_check() {
|
||||||
if (MonomorphicArrayCheck
|
if (MonomorphicArrayCheck
|
||||||
&& !too_many_traps(Deoptimization::Reason_array_check)
|
&& !too_many_traps(Deoptimization::Reason_array_check)
|
||||||
&& !tak->klass_is_exact()
|
&& !tak->klass_is_exact()
|
||||||
&& tak != TypeKlassPtr::OBJECT) {
|
&& tak != TypeInstKlassPtr::OBJECT) {
|
||||||
// Regarding the fourth condition in the if-statement from above:
|
// Regarding the fourth condition in the if-statement from above:
|
||||||
//
|
//
|
||||||
// If the compiler has determined that the type of array 'ary' (represented
|
// If the compiler has determined that the type of array 'ary' (represented
|
||||||
|
|
|
@ -234,7 +234,7 @@ bool SubTypeCheckNode::verify(PhaseGVN* phase) {
|
||||||
chk_off_X = phase->transform(new ConvI2LNode(chk_off_X));
|
chk_off_X = phase->transform(new ConvI2LNode(chk_off_X));
|
||||||
#endif
|
#endif
|
||||||
Node* p2 = phase->transform(new AddPNode(subklass, subklass, chk_off_X));
|
Node* p2 = phase->transform(new AddPNode(subklass, subklass, chk_off_X));
|
||||||
Node* nkls = phase->transform(LoadKlassNode::make(*phase, NULL, C->immutable_memory(), p2, phase->type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL));
|
Node* nkls = phase->transform(LoadKlassNode::make(*phase, NULL, C->immutable_memory(), p2, phase->type(p2)->is_ptr(), TypeInstKlassPtr::OBJECT_OR_NULL));
|
||||||
|
|
||||||
return verify_helper(phase, nkls, cached_t);
|
return verify_helper(phase, nkls, cached_t);
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -67,6 +67,8 @@ class TypeOopPtr;
|
||||||
class TypeInstPtr;
|
class TypeInstPtr;
|
||||||
class TypeAryPtr;
|
class TypeAryPtr;
|
||||||
class TypeKlassPtr;
|
class TypeKlassPtr;
|
||||||
|
class TypeInstKlassPtr;
|
||||||
|
class TypeAryKlassPtr;
|
||||||
class TypeMetadataPtr;
|
class TypeMetadataPtr;
|
||||||
|
|
||||||
//------------------------------Type-------------------------------------------
|
//------------------------------Type-------------------------------------------
|
||||||
|
@ -108,6 +110,8 @@ public:
|
||||||
|
|
||||||
MetadataPtr, // Generic metadata
|
MetadataPtr, // Generic metadata
|
||||||
KlassPtr, // Klass pointers
|
KlassPtr, // Klass pointers
|
||||||
|
InstKlassPtr,
|
||||||
|
AryKlassPtr,
|
||||||
|
|
||||||
Function, // Function signature
|
Function, // Function signature
|
||||||
Abio, // Abstract I/O
|
Abio, // Abstract I/O
|
||||||
|
@ -321,6 +325,10 @@ public:
|
||||||
const TypeMetadataPtr *is_metadataptr() const; // Java-style GC'd pointer
|
const TypeMetadataPtr *is_metadataptr() const; // Java-style GC'd pointer
|
||||||
const TypeKlassPtr *isa_klassptr() const; // Returns NULL if not KlassPtr
|
const TypeKlassPtr *isa_klassptr() const; // Returns NULL if not KlassPtr
|
||||||
const TypeKlassPtr *is_klassptr() const; // assert if not KlassPtr
|
const TypeKlassPtr *is_klassptr() const; // assert if not KlassPtr
|
||||||
|
const TypeInstKlassPtr *isa_instklassptr() const; // Returns NULL if not IntKlassPtr
|
||||||
|
const TypeInstKlassPtr *is_instklassptr() const; // assert if not IntKlassPtr
|
||||||
|
const TypeAryKlassPtr *isa_aryklassptr() const; // Returns NULL if not AryKlassPtr
|
||||||
|
const TypeAryKlassPtr *is_aryklassptr() const; // assert if not AryKlassPtr
|
||||||
|
|
||||||
virtual bool is_finite() const; // Has a finite value
|
virtual bool is_finite() const; // Has a finite value
|
||||||
virtual bool is_nan() const; // Is not a number (NaN)
|
virtual bool is_nan() const; // Is not a number (NaN)
|
||||||
|
@ -916,6 +924,24 @@ protected:
|
||||||
void dump_inline_depth(outputStream *st) const;
|
void dump_inline_depth(outputStream *st) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TypeInstPtr (TypeAryPtr resp.) and TypeInstKlassPtr (TypeAryKlassPtr resp.) implement very similar meet logic.
|
||||||
|
// The logic for meeting 2 instances (2 arrays resp.) is shared in the 2 utility methods below. However the logic for
|
||||||
|
// the oop and klass versions can be slightly different and extra logic may have to be executed depending on what
|
||||||
|
// exact case the meet falls into. The MeetResult struct is used by the utility methods to communicate what case was
|
||||||
|
// encountered so the right logic specific to klasses or oops can be executed.,
|
||||||
|
enum MeetResult {
|
||||||
|
QUICK,
|
||||||
|
UNLOADED,
|
||||||
|
SUBTYPE,
|
||||||
|
NOT_SUBTYPE,
|
||||||
|
LCA
|
||||||
|
};
|
||||||
|
static MeetResult
|
||||||
|
meet_instptr(PTR &ptr, ciKlass* this_klass, ciKlass* tinst_klass, bool this_xk, bool tinst_xk, PTR this_ptr,
|
||||||
|
PTR tinst_ptr, ciKlass*&res_klass, bool &res_xk);
|
||||||
|
static MeetResult
|
||||||
|
meet_aryptr(PTR& ptr, const Type*& elem, ciKlass* this_klass, ciKlass* tap_klass, bool this_xk, bool tap_xk, PTR this_ptr, PTR tap_ptr, ciKlass*& res_klass, bool& res_xk);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const int _offset; // Offset into oop, with TOP & BOT
|
const int _offset; // Offset into oop, with TOP & BOT
|
||||||
const PTR _ptr; // Pointer equivalence class
|
const PTR _ptr; // Pointer equivalence class
|
||||||
|
@ -998,7 +1024,7 @@ public:
|
||||||
static const TypeRawPtr *make( address bits );
|
static const TypeRawPtr *make( address bits );
|
||||||
|
|
||||||
// Return a 'ptr' version of this type
|
// Return a 'ptr' version of this type
|
||||||
virtual const Type *cast_to_ptr_type(PTR ptr) const;
|
virtual const TypeRawPtr* cast_to_ptr_type(PTR ptr) const;
|
||||||
|
|
||||||
virtual intptr_t get_con() const;
|
virtual intptr_t get_con() const;
|
||||||
|
|
||||||
|
@ -1097,14 +1123,14 @@ public:
|
||||||
|
|
||||||
virtual intptr_t get_con() const;
|
virtual intptr_t get_con() const;
|
||||||
|
|
||||||
virtual const Type *cast_to_ptr_type(PTR ptr) const;
|
virtual const TypeOopPtr* cast_to_ptr_type(PTR ptr) const;
|
||||||
|
|
||||||
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
|
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
|
||||||
|
|
||||||
virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
|
virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
|
||||||
|
|
||||||
// corresponding pointer to klass, for a given instance
|
// corresponding pointer to klass, for a given instance
|
||||||
const TypeKlassPtr* as_klass_type() const;
|
virtual const TypeKlassPtr* as_klass_type(bool try_for_exact = false) const;
|
||||||
|
|
||||||
virtual const TypePtr *add_offset( intptr_t offset ) const;
|
virtual const TypePtr *add_offset( intptr_t offset ) const;
|
||||||
|
|
||||||
|
@ -1181,7 +1207,7 @@ class TypeInstPtr : public TypeOopPtr {
|
||||||
// be a TypeInstPtr, but may also be a TypeInt::INT for int.class, etc.
|
// be a TypeInstPtr, but may also be a TypeInt::INT for int.class, etc.
|
||||||
ciType* java_mirror_type() const;
|
ciType* java_mirror_type() const;
|
||||||
|
|
||||||
virtual const Type *cast_to_ptr_type(PTR ptr) const;
|
virtual const TypeInstPtr* cast_to_ptr_type(PTR ptr) const;
|
||||||
|
|
||||||
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
|
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
|
||||||
|
|
||||||
|
@ -1199,6 +1225,8 @@ class TypeInstPtr : public TypeOopPtr {
|
||||||
virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const;
|
virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const;
|
||||||
virtual const Type *xdual() const; // Compute dual right now.
|
virtual const Type *xdual() const; // Compute dual right now.
|
||||||
|
|
||||||
|
const TypeKlassPtr* as_klass_type(bool try_for_exact = false) const;
|
||||||
|
|
||||||
// Convenience common pre-built types.
|
// Convenience common pre-built types.
|
||||||
static const TypeInstPtr *NOTNULL;
|
static const TypeInstPtr *NOTNULL;
|
||||||
static const TypeInstPtr *BOTTOM;
|
static const TypeInstPtr *BOTTOM;
|
||||||
|
@ -1265,7 +1293,7 @@ public:
|
||||||
int inline_depth = InlineDepthBottom, bool is_autobox_cache = false);
|
int inline_depth = InlineDepthBottom, bool is_autobox_cache = false);
|
||||||
|
|
||||||
// Return a 'ptr' version of this type
|
// Return a 'ptr' version of this type
|
||||||
virtual const Type *cast_to_ptr_type(PTR ptr) const;
|
virtual const TypeAryPtr* cast_to_ptr_type(PTR ptr) const;
|
||||||
|
|
||||||
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
|
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
|
||||||
|
|
||||||
|
@ -1292,6 +1320,7 @@ public:
|
||||||
const TypeAryPtr* cast_to_autobox_cache() const;
|
const TypeAryPtr* cast_to_autobox_cache() const;
|
||||||
|
|
||||||
static jint max_array_length(BasicType etype) ;
|
static jint max_array_length(BasicType etype) ;
|
||||||
|
virtual const TypeKlassPtr* as_klass_type(bool try_for_exact = false) const;
|
||||||
|
|
||||||
// Convenience common pre-built types.
|
// Convenience common pre-built types.
|
||||||
static const TypeAryPtr *RANGE;
|
static const TypeAryPtr *RANGE;
|
||||||
|
@ -1343,7 +1372,7 @@ public:
|
||||||
|
|
||||||
ciMetadata* metadata() const { return _metadata; }
|
ciMetadata* metadata() const { return _metadata; }
|
||||||
|
|
||||||
virtual const Type *cast_to_ptr_type(PTR ptr) const;
|
virtual const TypeMetadataPtr* cast_to_ptr_type(PTR ptr) const;
|
||||||
|
|
||||||
virtual const TypePtr *add_offset( intptr_t offset ) const;
|
virtual const TypePtr *add_offset( intptr_t offset ) const;
|
||||||
|
|
||||||
|
@ -1363,74 +1392,130 @@ public:
|
||||||
//------------------------------TypeKlassPtr-----------------------------------
|
//------------------------------TypeKlassPtr-----------------------------------
|
||||||
// Class of Java Klass pointers
|
// Class of Java Klass pointers
|
||||||
class TypeKlassPtr : public TypePtr {
|
class TypeKlassPtr : public TypePtr {
|
||||||
TypeKlassPtr( PTR ptr, ciKlass* klass, int offset );
|
protected:
|
||||||
|
TypeKlassPtr(TYPES t, PTR ptr, ciKlass* klass, int offset);
|
||||||
|
|
||||||
|
virtual const Type *filter_helper(const Type *kills, bool include_speculative) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool eq( const Type *t ) const;
|
||||||
|
virtual int hash() const;
|
||||||
|
virtual bool singleton(void) const; // TRUE if type is a singleton
|
||||||
|
virtual bool must_be_exact() const { ShouldNotReachHere(); return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual const Type *filter_helper(const Type *kills, bool include_speculative) const;
|
|
||||||
public:
|
|
||||||
virtual bool eq( const Type *t ) const;
|
|
||||||
virtual int hash() const; // Type specific hashing
|
|
||||||
virtual bool singleton(void) const; // TRUE if type is a singleton
|
|
||||||
private:
|
|
||||||
|
|
||||||
static const TypeKlassPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact);
|
|
||||||
|
|
||||||
ciKlass* _klass;
|
ciKlass* _klass;
|
||||||
|
|
||||||
// Does the type exclude subclasses of the klass? (Inexact == polymorphic.)
|
|
||||||
bool _klass_is_exact;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ciSymbol* name() const { return klass()->name(); }
|
|
||||||
|
|
||||||
ciKlass* klass() const { return _klass; }
|
|
||||||
bool klass_is_exact() const { return _klass_is_exact; }
|
|
||||||
|
|
||||||
|
virtual ciKlass* klass() const { return _klass; }
|
||||||
|
bool klass_is_exact() const { return _ptr == Constant; }
|
||||||
bool is_loaded() const { return klass()->is_loaded(); }
|
bool is_loaded() const { return klass()->is_loaded(); }
|
||||||
|
|
||||||
// Creates a type given a klass. Correctly handles multi-dimensional arrays
|
static const TypeKlassPtr* make(ciKlass* klass);
|
||||||
// Respects UseUniqueSubclasses.
|
static const TypeKlassPtr *make(PTR ptr, ciKlass* klass, int offset);
|
||||||
// If the klass is final, the resulting type will be exact.
|
|
||||||
static const TypeKlassPtr* make_from_klass(ciKlass* klass) {
|
|
||||||
return make_from_klass_common(klass, true, false);
|
|
||||||
}
|
|
||||||
// Same as before, but will produce an exact type, even if
|
|
||||||
// the klass is not final, as long as it has exactly one implementation.
|
|
||||||
static const TypeKlassPtr* make_from_klass_unique(ciKlass* klass) {
|
|
||||||
return make_from_klass_common(klass, true, true);
|
|
||||||
}
|
|
||||||
// Same as before, but does not respects UseUniqueSubclasses.
|
|
||||||
// Use this only for creating array element types.
|
|
||||||
static const TypeKlassPtr* make_from_klass_raw(ciKlass* klass) {
|
|
||||||
return make_from_klass_common(klass, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a generic (unclassed) pointer to metadata.
|
|
||||||
static const TypeKlassPtr* make(PTR ptr, int offset);
|
|
||||||
|
|
||||||
// ptr to klass 'k'
|
virtual const TypePtr* cast_to_ptr_type(PTR ptr) const { ShouldNotReachHere(); return NULL; }
|
||||||
static const TypeKlassPtr *make( ciKlass* k ) { return make( TypePtr::Constant, k, 0); }
|
|
||||||
// ptr to klass 'k' with offset
|
|
||||||
static const TypeKlassPtr *make( ciKlass* k, int offset ) { return make( TypePtr::Constant, k, offset); }
|
|
||||||
// ptr to klass 'k' or sub-klass
|
|
||||||
static const TypeKlassPtr *make( PTR ptr, ciKlass* k, int offset);
|
|
||||||
|
|
||||||
virtual const Type *cast_to_ptr_type(PTR ptr) const;
|
virtual const TypeKlassPtr *cast_to_exactness(bool klass_is_exact) const { ShouldNotReachHere(); return NULL; }
|
||||||
|
|
||||||
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
|
|
||||||
|
|
||||||
// corresponding pointer to instance, for a given class
|
// corresponding pointer to instance, for a given class
|
||||||
const TypeOopPtr* as_instance_type() const;
|
virtual const TypeOopPtr* as_instance_type() const { ShouldNotReachHere(); return NULL; }
|
||||||
|
|
||||||
|
virtual const TypePtr *add_offset( intptr_t offset ) const { ShouldNotReachHere(); return NULL; }
|
||||||
|
virtual const Type *xmeet( const Type *t ) const { ShouldNotReachHere(); return NULL; }
|
||||||
|
virtual const Type *xdual() const { ShouldNotReachHere(); return NULL; }
|
||||||
|
|
||||||
|
virtual intptr_t get_con() const;
|
||||||
|
|
||||||
|
virtual const TypeKlassPtr* with_offset(intptr_t offset) const { ShouldNotReachHere(); return NULL; }
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// Instance klass pointer, mirrors TypeInstPtr
|
||||||
|
class TypeInstKlassPtr : public TypeKlassPtr {
|
||||||
|
|
||||||
|
TypeInstKlassPtr(PTR ptr, ciKlass* klass, int offset)
|
||||||
|
: TypeKlassPtr(InstKlassPtr, ptr, klass, offset) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool must_be_exact() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Instance klass ignoring any interface
|
||||||
|
ciInstanceKlass* instance_klass() const { return klass()->as_instance_klass(); }
|
||||||
|
|
||||||
|
static const TypeInstKlassPtr *make(ciKlass* k) {
|
||||||
|
return make(TypePtr::Constant, k, 0);
|
||||||
|
}
|
||||||
|
static const TypeInstKlassPtr *make(PTR ptr, ciKlass* k, int offset);
|
||||||
|
|
||||||
|
virtual const TypePtr* cast_to_ptr_type(PTR ptr) const;
|
||||||
|
|
||||||
|
virtual const TypeKlassPtr *cast_to_exactness(bool klass_is_exact) const;
|
||||||
|
|
||||||
|
// corresponding pointer to instance, for a given class
|
||||||
|
virtual const TypeOopPtr* as_instance_type() const;
|
||||||
|
virtual int hash() const;
|
||||||
|
virtual bool eq(const Type *t) const;
|
||||||
|
|
||||||
|
virtual const TypePtr *add_offset( intptr_t offset ) const;
|
||||||
|
virtual const Type *xmeet( const Type *t ) const;
|
||||||
|
virtual const Type *xdual() const;
|
||||||
|
virtual const TypeKlassPtr* with_offset(intptr_t offset) const;
|
||||||
|
|
||||||
|
// Convenience common pre-built types.
|
||||||
|
static const TypeInstKlassPtr* OBJECT; // Not-null object klass or below
|
||||||
|
static const TypeInstKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same
|
||||||
|
};
|
||||||
|
|
||||||
|
// Array klass pointer, mirrors TypeAryPtr
|
||||||
|
class TypeAryKlassPtr : public TypeKlassPtr {
|
||||||
|
const Type *_elem;
|
||||||
|
|
||||||
|
TypeAryKlassPtr(PTR ptr, const Type *elem, ciKlass* klass, int offset)
|
||||||
|
: TypeKlassPtr(AryKlassPtr, ptr, klass, offset), _elem(elem) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool must_be_exact() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ciKlass* klass() const;
|
||||||
|
|
||||||
|
// returns base element type, an instance klass (and not interface) for object arrays
|
||||||
|
const Type* base_element_type(int& dims) const;
|
||||||
|
|
||||||
|
static const TypeAryKlassPtr *make(PTR ptr, ciKlass* k, int offset);
|
||||||
|
static const TypeAryKlassPtr *make(PTR ptr, const Type *elem, ciKlass* k, int offset);
|
||||||
|
static const TypeAryKlassPtr* make(ciKlass* klass);
|
||||||
|
|
||||||
|
const Type *elem() const { return _elem; }
|
||||||
|
|
||||||
|
virtual bool eq(const Type *t) const;
|
||||||
|
virtual int hash() const; // Type specific hashing
|
||||||
|
|
||||||
|
virtual const TypePtr* cast_to_ptr_type(PTR ptr) const;
|
||||||
|
|
||||||
|
virtual const TypeKlassPtr *cast_to_exactness(bool klass_is_exact) const;
|
||||||
|
|
||||||
|
// corresponding pointer to instance, for a given class
|
||||||
|
virtual const TypeOopPtr* as_instance_type() const;
|
||||||
|
|
||||||
virtual const TypePtr *add_offset( intptr_t offset ) const;
|
virtual const TypePtr *add_offset( intptr_t offset ) const;
|
||||||
virtual const Type *xmeet( const Type *t ) const;
|
virtual const Type *xmeet( const Type *t ) const;
|
||||||
virtual const Type *xdual() const; // Compute dual right now.
|
virtual const Type *xdual() const; // Compute dual right now.
|
||||||
|
|
||||||
virtual intptr_t get_con() const;
|
virtual const TypeKlassPtr* with_offset(intptr_t offset) const;
|
||||||
|
|
||||||
|
virtual bool empty(void) const {
|
||||||
|
return TypeKlassPtr::empty() || _elem->empty();
|
||||||
|
}
|
||||||
|
|
||||||
// Convenience common pre-built types.
|
|
||||||
static const TypeKlassPtr* OBJECT; // Not-null object klass or below
|
|
||||||
static const TypeKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
|
virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
|
||||||
#endif
|
#endif
|
||||||
|
@ -1721,13 +1806,13 @@ inline const TypeVect *Type::isa_vect() const {
|
||||||
|
|
||||||
inline const TypePtr *Type::is_ptr() const {
|
inline const TypePtr *Type::is_ptr() const {
|
||||||
// AnyPtr is the first Ptr and KlassPtr the last, with no non-ptrs between.
|
// AnyPtr is the first Ptr and KlassPtr the last, with no non-ptrs between.
|
||||||
assert(_base >= AnyPtr && _base <= KlassPtr, "Not a pointer");
|
assert(_base >= AnyPtr && _base <= AryKlassPtr, "Not a pointer");
|
||||||
return (TypePtr*)this;
|
return (TypePtr*)this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const TypePtr *Type::isa_ptr() const {
|
inline const TypePtr *Type::isa_ptr() const {
|
||||||
// AnyPtr is the first Ptr and KlassPtr the last, with no non-ptrs between.
|
// AnyPtr is the first Ptr and KlassPtr the last, with no non-ptrs between.
|
||||||
return (_base >= AnyPtr && _base <= KlassPtr) ? (TypePtr*)this : NULL;
|
return (_base >= AnyPtr && _base <= AryKlassPtr) ? (TypePtr*)this : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const TypeOopPtr *Type::is_oopptr() const {
|
inline const TypeOopPtr *Type::is_oopptr() const {
|
||||||
|
@ -1799,14 +1884,32 @@ inline const TypeMetadataPtr *Type::isa_metadataptr() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const TypeKlassPtr *Type::isa_klassptr() const {
|
inline const TypeKlassPtr *Type::isa_klassptr() const {
|
||||||
return (_base == KlassPtr) ? (TypeKlassPtr*)this : NULL;
|
return (_base >= KlassPtr && _base <= AryKlassPtr ) ? (TypeKlassPtr*)this : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const TypeKlassPtr *Type::is_klassptr() const {
|
inline const TypeKlassPtr *Type::is_klassptr() const {
|
||||||
assert( _base == KlassPtr, "Not a klass pointer" );
|
assert(_base >= KlassPtr && _base <= AryKlassPtr, "Not a klass pointer");
|
||||||
return (TypeKlassPtr*)this;
|
return (TypeKlassPtr*)this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const TypeInstKlassPtr *Type::isa_instklassptr() const {
|
||||||
|
return (_base == InstKlassPtr) ? (TypeInstKlassPtr*)this : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const TypeInstKlassPtr *Type::is_instklassptr() const {
|
||||||
|
assert(_base == InstKlassPtr, "Not a klass pointer");
|
||||||
|
return (TypeInstKlassPtr*)this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const TypeAryKlassPtr *Type::isa_aryklassptr() const {
|
||||||
|
return (_base == AryKlassPtr) ? (TypeAryKlassPtr*)this : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const TypeAryKlassPtr *Type::is_aryklassptr() const {
|
||||||
|
assert(_base == AryKlassPtr, "Not a klass pointer");
|
||||||
|
return (TypeAryKlassPtr*)this;
|
||||||
|
}
|
||||||
|
|
||||||
inline const TypePtr* Type::make_ptr() const {
|
inline const TypePtr* Type::make_ptr() const {
|
||||||
return (_base == NarrowOop) ? is_narrowoop()->get_ptrtype() :
|
return (_base == NarrowOop) ? is_narrowoop()->get_ptrtype() :
|
||||||
((_base == NarrowKlass) ? is_narrowklass()->get_ptrtype() :
|
((_base == NarrowKlass) ? is_narrowklass()->get_ptrtype() :
|
||||||
|
|
|
@ -447,7 +447,7 @@ public:
|
||||||
|
|
||||||
// Binary search and insertion utility. Search array for element
|
// Binary search and insertion utility. Search array for element
|
||||||
// matching key according to the static compare function. Insert
|
// matching key according to the static compare function. Insert
|
||||||
// that element is not already in the list. Assumes the list is
|
// that element if not already in the list. Assumes the list is
|
||||||
// already sorted according to compare function.
|
// already sorted according to compare function.
|
||||||
template <int compare(const E&, const E&)> E insert_sorted(const E& key) {
|
template <int compare(const E&, const E&)> E insert_sorted(const E& key) {
|
||||||
bool found;
|
bool found;
|
||||||
|
|
|
@ -53,13 +53,13 @@ public class IRNode {
|
||||||
private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END;
|
private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END;
|
||||||
private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END;
|
private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END;
|
||||||
|
|
||||||
public static final String ALLOC = "(.*precise klass .*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END;
|
public static final String ALLOC = "(.*precise .*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END;
|
||||||
public static final String ALLOC_OF = COMPOSITE_PREFIX + "(.*precise klass .*" + IS_REPLACED + ":.*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END;
|
public static final String ALLOC_OF = COMPOSITE_PREFIX + "(.*precise .*" + IS_REPLACED + ":.*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END;
|
||||||
public static final String ALLOC_ARRAY = "(.*precise klass \\[L.*\\R((.*(?i:mov|xor|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END;
|
public static final String ALLOC_ARRAY = "(.*precise \\[.*\\R((.*(?i:mov|xor|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END;
|
||||||
public static final String ALLOC_ARRAY_OF = COMPOSITE_PREFIX + "(.*precise klass \\[L.*" + IS_REPLACED + ";:.*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END;
|
public static final String ALLOC_ARRAY_OF = COMPOSITE_PREFIX + "(.*precise \\[.*" + IS_REPLACED + ":.*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END;
|
||||||
|
|
||||||
public static final String CHECKCAST_ARRAY = "(((?i:cmp|CLFI|CLR).*precise klass \\[.*;:|.*(?i:mov|or).*precise klass \\[.*;:.*\\R.*(cmp|CMP|CLR))" + END;
|
public static final String CHECKCAST_ARRAY = "(((?i:cmp|CLFI|CLR).*precise \\[.*:|.*(?i:mov|or).*precise \\[.*:.*\\R.*(cmp|CMP|CLR))" + END;
|
||||||
public static final String CHECKCAST_ARRAY_OF = COMPOSITE_PREFIX + "(((?i:cmp|CLFI|CLR).*precise klass \\[.*" + IS_REPLACED + ";:|.*(?i:mov|or).*precise klass \\[.*" + IS_REPLACED + ";:.*\\R.*(cmp|CMP|CLR))" + END;
|
public static final String CHECKCAST_ARRAY_OF = COMPOSITE_PREFIX + "(((?i:cmp|CLFI|CLR).*precise \\[.*" + IS_REPLACED + ":|.*(?i:mov|or).*precise klass \\[.*" + IS_REPLACED + ";:.*\\R.*(cmp|CMP|CLR))" + END;
|
||||||
// Does not work on s390 (a rule containing this regex will be skipped on s390).
|
// Does not work on s390 (a rule containing this regex will be skipped on s390).
|
||||||
public static final String CHECKCAST_ARRAYCOPY = "(.*((?i:call_leaf_nofp,runtime)|CALL,\\s?runtime leaf nofp|BCTRL.*.leaf call).*checkcast_arraycopy.*" + END;
|
public static final String CHECKCAST_ARRAYCOPY = "(.*((?i:call_leaf_nofp,runtime)|CALL,\\s?runtime leaf nofp|BCTRL.*.leaf call).*checkcast_arraycopy.*" + END;
|
||||||
|
|
||||||
|
|
|
@ -207,9 +207,9 @@ public class TestIRMatching {
|
||||||
} else {
|
} else {
|
||||||
cmp = "cmp";
|
cmp = "cmp";
|
||||||
}
|
}
|
||||||
runCheck(BadFailOnConstraint.create(CheckCastArray.class, "array()", 1, cmp, "precise klass"),
|
runCheck(BadFailOnConstraint.create(CheckCastArray.class, "array()", 1, cmp, "precise"),
|
||||||
BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 1,cmp, "precise klass", "MyClass"),
|
BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 1,cmp, "precise", "MyClass"),
|
||||||
BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 2,cmp, "precise klass", "ir_framework/tests/MyClass"),
|
BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 2,cmp, "precise", "ir_framework/tests/MyClass"),
|
||||||
GoodFailOnConstraint.create(CheckCastArray.class, "array()", 3),
|
GoodFailOnConstraint.create(CheckCastArray.class, "array()", 3),
|
||||||
Platform.isS390x() ? // There is no checkcast_arraycopy stub for C2 on s390
|
Platform.isS390x() ? // There is no checkcast_arraycopy stub for C2 on s390
|
||||||
GoodFailOnConstraint.create(CheckCastArray.class, "arrayCopy(java.lang.Object[],java.lang.Class)", 1)
|
GoodFailOnConstraint.create(CheckCastArray.class, "arrayCopy(java.lang.Object[],java.lang.Class)", 1)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue