src/share/vm/opto/type.cpp
Print this page
@@ -55,10 +55,11 @@
{ Bottom, T_VOID, "top", false, 0, relocInfo::none }, // Top
{ Bad, T_INT, "int:", false, Op_RegI, relocInfo::none }, // Int
{ Bad, T_LONG, "long:", false, Op_RegL, relocInfo::none }, // Long
{ Half, T_VOID, "half", false, 0, relocInfo::none }, // Half
{ Bad, T_NARROWOOP, "narrowoop:", false, Op_RegN, relocInfo::none }, // NarrowOop
+ { Bad, T_NARROWKLASS,"narrowklass:", false, Op_RegN, relocInfo::none }, // NarrowKlass
{ Bad, T_ILLEGAL, "tuple:", false, Node::NotAMachineReg, relocInfo::none }, // Tuple
{ Bad, T_ARRAY, "array:", false, Node::NotAMachineReg, relocInfo::none }, // Array
#if defined(IA32) || defined(AMD64)
{ Bad, T_ILLEGAL, "vectors:", false, Op_VecS, relocInfo::none }, // VectorS
@@ -330,10 +331,12 @@
TypeMetadataPtr::BOTTOM = TypeMetadataPtr::make(TypePtr::BotPTR, NULL, OffsetBot);
TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR );
TypeNarrowOop::BOTTOM = TypeNarrowOop::make( TypeInstPtr::BOTTOM );
+ TypeNarrowKlass::NULL_PTR = TypeNarrowKlass::make( TypePtr::NULL_PTR );
+
mreg2type[Op_Node] = Type::BOTTOM;
mreg2type[Op_Set ] = 0;
mreg2type[Op_RegN] = TypeNarrowOop::BOTTOM;
mreg2type[Op_RegI] = TypeInt::INT;
mreg2type[Op_RegP] = TypePtr::BOTTOM;
@@ -394,10 +397,11 @@
longpair[0] = TypeLong::LONG;
longpair[1] = TypeLong::LONG;
TypeTuple::LONG_PAIR = TypeTuple::make(2, longpair);
_const_basic_type[T_NARROWOOP] = TypeNarrowOop::BOTTOM;
+ _const_basic_type[T_NARROWKLASS] = Type::BOTTOM;
_const_basic_type[T_BOOLEAN] = TypeInt::BOOL;
_const_basic_type[T_CHAR] = TypeInt::CHAR;
_const_basic_type[T_BYTE] = TypeInt::BYTE;
_const_basic_type[T_SHORT] = TypeInt::SHORT;
_const_basic_type[T_INT] = TypeInt::INT;
@@ -406,13 +410,14 @@
_const_basic_type[T_DOUBLE] = Type::DOUBLE;
_const_basic_type[T_OBJECT] = TypeInstPtr::BOTTOM;
_const_basic_type[T_ARRAY] = TypeInstPtr::BOTTOM; // there is no separate bottom for arrays
_const_basic_type[T_VOID] = TypePtr::NULL_PTR; // reflection represents void this way
_const_basic_type[T_ADDRESS] = TypeRawPtr::BOTTOM; // both interpreter return addresses & random raw ptrs
- _const_basic_type[T_CONFLICT]= Type::BOTTOM; // why not?
+ _const_basic_type[T_CONFLICT] = Type::BOTTOM; // why not?
_zero_type[T_NARROWOOP] = TypeNarrowOop::NULL_PTR;
+ _zero_type[T_NARROWKLASS] = TypeNarrowKlass::NULL_PTR;
_zero_type[T_BOOLEAN] = TypeInt::ZERO; // false == 0
_zero_type[T_CHAR] = TypeInt::ZERO; // '\0' == 0
_zero_type[T_BYTE] = TypeInt::ZERO; // 0x00 == 0
_zero_type[T_SHORT] = TypeInt::ZERO; // 0x0000 == 0
_zero_type[T_INT] = TypeInt::ZERO;
@@ -561,13 +566,18 @@
const Type *Type::meet( const Type *t ) const {
if (isa_narrowoop() && t->isa_narrowoop()) {
const Type* result = make_ptr()->meet(t->make_ptr());
return result->make_narrowoop();
}
+ if (isa_narrowklass() && t->isa_narrowklass()) {
+ const Type* result = make_ptr()->meet(t->make_ptr());
+ return result->make_narrowklass();
+ }
const Type *mt = xmeet(t);
if (isa_narrowoop() || t->isa_narrowoop()) return mt;
+ if (isa_narrowklass() || t->isa_narrowklass()) return mt;
#ifdef ASSERT
assert( mt == t->xmeet(this), "meet not commutative" );
const Type* dual_join = mt->_dual;
const Type *t2t = dual_join->xmeet(t->_dual);
const Type *t2this = dual_join->xmeet( _dual);
@@ -633,10 +643,13 @@
return t->xmeet(this);
case NarrowOop:
return t->xmeet(this);
+ case NarrowKlass:
+ return t->xmeet(this);
+
case Bad: // Type check
default: // Bogus type not in lattice
typerr(t);
return Type::BOTTOM;
@@ -691,10 +704,11 @@
Bottom, // Top
Bad, // Int - handled in v-call
Bad, // Long - handled in v-call
Half, // Half
Bad, // NarrowOop - handled in v-call
+ Bad, // NarrowKlass - handled in v-call
Bad, // Tuple - handled in v-call
Bad, // Array - handled in v-call
Bad, // VectorS - handled in v-call
Bad, // VectorD - handled in v-call
@@ -754,10 +768,12 @@
ResourceMark rm;
Dict d(cmpkey,hashkey); // Stop recursive type dumping
dump2(d,1, st);
if (is_ptr_to_narrowoop()) {
st->print(" [narrow]");
+ } else if (is_ptr_to_narrowklass()) {
+ st->print(" [narrowklass]");
}
}
#endif
//------------------------------singleton--------------------------------------
@@ -836,10 +852,11 @@
case InstPtr:
case AryPtr:
case MetadataPtr:
case KlassPtr:
case NarrowOop:
+ case NarrowKlass:
case Int:
case Long:
case DoubleTop:
case DoubleCon:
case DoubleBot:
@@ -953,10 +970,11 @@
case InstPtr:
case AryPtr:
case MetadataPtr:
case KlassPtr:
case NarrowOop:
+ case NarrowKlass:
case Int:
case Long:
case FloatTop:
case FloatCon:
case FloatBot:
@@ -1107,10 +1125,11 @@
case InstPtr:
case AryPtr:
case MetadataPtr:
case KlassPtr:
case NarrowOop:
+ case NarrowKlass:
case Long:
case FloatTop:
case FloatCon:
case FloatBot:
case DoubleTop:
@@ -1364,10 +1383,11 @@
case InstPtr:
case AryPtr:
case MetadataPtr:
case KlassPtr:
case NarrowOop:
+ case NarrowKlass:
case Int:
case FloatTop:
case FloatCon:
case FloatBot:
case DoubleTop:
@@ -2094,10 +2114,11 @@
case FloatBot:
case DoubleTop:
case DoubleCon:
case DoubleBot:
case NarrowOop:
+ case NarrowKlass:
case Bottom: // Ye Olde Default
return Type::BOTTOM;
case Top:
return this;
@@ -2348,30 +2369,31 @@
TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id )
: TypePtr(t, ptr, offset),
_const_oop(o), _klass(k),
_klass_is_exact(xk),
_is_ptr_to_narrowoop(false),
+ _is_ptr_to_narrowklass(false),
_instance_id(instance_id) {
#ifdef _LP64
- if (UseCompressedOops && _offset != 0) {
+ if (_offset != 0) {
if (_offset == oopDesc::klass_offset_in_bytes()) {
- _is_ptr_to_narrowoop = UseCompressedKlassPointers;
+ _is_ptr_to_narrowklass = UseCompressedKlassPointers;
} else if (klass() == NULL) {
// Array with unknown body type
assert(this->isa_aryptr(), "only arrays without klass");
- _is_ptr_to_narrowoop = true;
+ _is_ptr_to_narrowoop = UseCompressedOops;
} else if (this->isa_aryptr()) {
- _is_ptr_to_narrowoop = (klass()->is_obj_array_klass() &&
+ _is_ptr_to_narrowoop = (UseCompressedOops && klass()->is_obj_array_klass() &&
_offset != arrayOopDesc::length_offset_in_bytes());
} else if (klass()->is_instance_klass()) {
ciInstanceKlass* ik = klass()->as_instance_klass();
ciField* field = NULL;
if (this->isa_klassptr()) {
// Perm objects don't use compressed references
} else if (_offset == OffsetBot || _offset == OffsetTop) {
// unsafe access
- _is_ptr_to_narrowoop = true;
+ _is_ptr_to_narrowoop = UseCompressedOops;
} else { // exclude unsafe ops
assert(this->isa_instptr(), "must be an instance ptr.");
if (klass() == ciEnv::current()->Class_klass() &&
(_offset == java_lang_Class::klass_offset_in_bytes() ||
@@ -2385,26 +2407,26 @@
assert(o != NULL, "must be constant");
ciInstanceKlass* k = o->as_instance()->java_lang_Class_klass()->as_instance_klass();
ciField* field = k->get_field_by_offset(_offset, true);
assert(field != NULL, "missing field");
BasicType basic_elem_type = field->layout_type();
- _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT ||
+ _is_ptr_to_narrowoop = UseCompressedOops && (basic_elem_type == T_OBJECT ||
basic_elem_type == T_ARRAY);
} else {
// Instance fields which contains a compressed oop references.
field = ik->get_field_by_offset(_offset, false);
if (field != NULL) {
BasicType basic_elem_type = field->layout_type();
- _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT ||
+ _is_ptr_to_narrowoop = UseCompressedOops && (basic_elem_type == T_OBJECT ||
basic_elem_type == T_ARRAY);
} else if (klass()->equals(ciEnv::current()->Object_klass())) {
// Compile::find_alias_type() cast exactness on all types to verify
// that it does not affect alias type.
- _is_ptr_to_narrowoop = true;
+ _is_ptr_to_narrowoop = UseCompressedOops;
} else {
// Type for the copy start in LibraryCallKit::inline_native_clone().
- _is_ptr_to_narrowoop = true;
+ _is_ptr_to_narrowoop = UseCompressedOops;
}
}
}
}
}
@@ -2473,10 +2495,11 @@
case FloatBot:
case DoubleTop:
case DoubleCon:
case DoubleBot:
case NarrowOop:
+ case NarrowKlass:
case Bottom: // Ye Olde Default
return Type::BOTTOM;
case Top:
return this;
@@ -2923,10 +2946,11 @@
case FloatBot:
case DoubleTop:
case DoubleCon:
case DoubleBot:
case NarrowOop:
+ case NarrowKlass:
case Bottom: // Ye Olde Default
return Type::BOTTOM;
case Top:
return this;
@@ -3351,10 +3375,11 @@
if (res == 0) {
switch (etype) {
case T_NARROWOOP:
etype = T_OBJECT;
break;
+ case T_NARROWKLASS:
case T_CONFLICT:
case T_ILLEGAL:
case T_VOID:
etype = T_BYTE; // will produce conservatively high value
}
@@ -3423,10 +3448,11 @@
case FloatBot:
case DoubleTop:
case DoubleCon:
case DoubleBot:
case NarrowOop:
+ case NarrowKlass:
case Bottom: // Ye Olde Default
return Type::BOTTOM;
case Top:
return this;
@@ -3669,52 +3695,80 @@
return make( _ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id );
}
//=============================================================================
-const TypeNarrowOop *TypeNarrowOop::BOTTOM;
-const TypeNarrowOop *TypeNarrowOop::NULL_PTR;
-
-
-const TypeNarrowOop* TypeNarrowOop::make(const TypePtr* type) {
- return (const TypeNarrowOop*)(new TypeNarrowOop(type))->hashcons();
-}
//------------------------------hash-------------------------------------------
// Type-specific hashing function.
-int TypeNarrowOop::hash(void) const {
+int TypeNarrowPtr::hash(void) const {
return _ptrtype->hash() + 7;
}
+bool TypeNarrowPtr::singleton(void) const { // TRUE if type is a singleton
+ return _ptrtype->singleton();
+}
+
+bool TypeNarrowPtr::empty(void) const {
+ return _ptrtype->empty();
+}
+
+intptr_t TypeNarrowPtr::get_con() const {
+ return _ptrtype->get_con();
+}
-bool TypeNarrowOop::eq( const Type *t ) const {
- const TypeNarrowOop* tc = t->isa_narrowoop();
+bool TypeNarrowPtr::eq( const Type *t ) const {
+ const TypeNarrowPtr* tc = isa_same_narrowptr(t);
if (tc != NULL) {
if (_ptrtype->base() != tc->_ptrtype->base()) {
return false;
}
return tc->_ptrtype->eq(_ptrtype);
}
return false;
}
-bool TypeNarrowOop::singleton(void) const { // TRUE if type is a singleton
- return _ptrtype->singleton();
+const Type *TypeNarrowPtr::xdual() const { // Compute dual right now.
+ const TypePtr* odual = _ptrtype->dual()->is_ptr();
+ return make_same_narrowptr(odual);
}
-bool TypeNarrowOop::empty(void) const {
- return _ptrtype->empty();
+
+const Type *TypeNarrowPtr::filter( const Type *kills ) const {
+ if (isa_same_narrowptr(kills)) {
+ const Type* ft =_ptrtype->filter(is_same_narrowptr(kills)->_ptrtype);
+ if (ft->empty())
+ return Type::TOP; // Canonical empty value
+ if (ft->isa_ptr()) {
+ return make_hash_same_narrowptr(ft->isa_ptr());
+ }
+ return ft;
+ } else if (kills->isa_ptr()) {
+ const Type* ft = _ptrtype->join(kills);
+ if (ft->empty())
+ return Type::TOP; // Canonical empty value
+ return ft;
+ } else {
+ return Type::TOP;
+ }
}
//------------------------------xmeet------------------------------------------
// Compute the MEET of two types. It returns a new Type object.
-const Type *TypeNarrowOop::xmeet( const Type *t ) const {
+const Type *TypeNarrowPtr::xmeet( const Type *t ) const {
// Perform a fast test for common case; meeting the same types together.
if( this == t ) return this; // Meeting same type-rep?
+ if (t->base() == base()) {
+ const Type* result = _ptrtype->xmeet(t->make_ptr());
+ if (result->isa_ptr()) {
+ return make_hash_same_narrowptr(result->is_ptr());
+ }
+ return result;
+ }
- // Current "this->_base" is OopPtr
+ // Current "this->_base" is NarrowKlass or NarrowOop
switch (t->base()) { // switch on original type
case Int: // Mixing ints & oops happens when javac
case Long: // reuses local variables
case FloatTop:
@@ -3728,68 +3782,60 @@
case OopPtr:
case InstPtr:
case AryPtr:
case MetadataPtr:
case KlassPtr:
+ case NarrowOop:
+ case NarrowKlass:
case Bottom: // Ye Olde Default
return Type::BOTTOM;
case Top:
return this;
- case NarrowOop: {
- const Type* result = _ptrtype->xmeet(t->make_ptr());
- if (result->isa_ptr()) {
- return TypeNarrowOop::make(result->is_ptr());
- }
- return result;
- }
-
default: // All else is a mistake
typerr(t);
} // End of switch
return this;
}
-const Type *TypeNarrowOop::xdual() const { // Compute dual right now.
- const TypePtr* odual = _ptrtype->dual()->is_ptr();
- return new TypeNarrowOop(odual);
+#ifndef PRODUCT
+void TypeNarrowPtr::dump2( Dict & d, uint depth, outputStream *st ) const {
+ _ptrtype->dump2(d, depth, st);
}
+#endif
-const Type *TypeNarrowOop::filter( const Type *kills ) const {
- if (kills->isa_narrowoop()) {
- const Type* ft =_ptrtype->filter(kills->is_narrowoop()->_ptrtype);
- if (ft->empty())
- return Type::TOP; // Canonical empty value
- if (ft->isa_ptr()) {
- return make(ft->isa_ptr());
- }
- return ft;
- } else if (kills->isa_ptr()) {
- const Type* ft = _ptrtype->join(kills);
- if (ft->empty())
- return Type::TOP; // Canonical empty value
- return ft;
- } else {
- return Type::TOP;
- }
-}
+const TypeNarrowOop *TypeNarrowOop::BOTTOM;
+const TypeNarrowOop *TypeNarrowOop::NULL_PTR;
-intptr_t TypeNarrowOop::get_con() const {
- return _ptrtype->get_con();
+const TypeNarrowOop* TypeNarrowOop::make(const TypePtr* type) {
+ return (const TypeNarrowOop*)(new TypeNarrowOop(type))->hashcons();
}
+
#ifndef PRODUCT
void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const {
st->print("narrowoop: ");
- _ptrtype->dump2(d, depth, st);
+ TypeNarrowPtr::dump2(d, depth, st);
}
#endif
+const TypeNarrowKlass *TypeNarrowKlass::NULL_PTR;
+
+const TypeNarrowKlass* TypeNarrowKlass::make(const TypePtr* type) {
+ return (const TypeNarrowKlass*)(new TypeNarrowKlass(type))->hashcons();
+}
+
+#ifndef PRODUCT
+void TypeNarrowKlass::dump2( Dict & d, uint depth, outputStream *st ) const {
+ st->print("narrowklass: ");
+ TypeNarrowPtr::dump2(d, depth, st);
+}
+#endif
//------------------------------eq---------------------------------------------
// Structural equality check for Type representations
bool TypeMetadataPtr::eq( const Type *t ) const {
@@ -3876,10 +3922,11 @@
case FloatBot:
case DoubleTop:
case DoubleCon:
case DoubleBot:
case NarrowOop:
+ case NarrowKlass:
case Bottom: // Ye Olde Default
return Type::BOTTOM;
case Top:
return this;
@@ -4167,10 +4214,11 @@
case FloatBot:
case DoubleTop:
case DoubleCon:
case DoubleBot:
case NarrowOop:
+ case NarrowKlass:
case Bottom: // Ye Olde Default
return Type::BOTTOM;
case Top:
return this;