src/share/vm/opto/type.cpp

changeset 548
ba764ed4b6f2
parent 499
b8f5ba577b02
child 598
885ed790ecf0
     1.1 --- a/src/share/vm/opto/type.cpp	Fri Apr 11 09:56:35 2008 -0400
     1.2 +++ b/src/share/vm/opto/type.cpp	Sun Apr 13 17:43:42 2008 -0400
     1.3 @@ -40,6 +40,7 @@
     1.4    T_INT,        // Int
     1.5    T_LONG,       // Long
     1.6    T_VOID,       // Half
     1.7 +  T_NARROWOOP,  // NarrowOop
     1.8  
     1.9    T_ILLEGAL,    // Tuple
    1.10    T_ARRAY,      // Array
    1.11 @@ -279,15 +280,6 @@
    1.12    TypeRawPtr::BOTTOM = TypeRawPtr::make( TypePtr::BotPTR );
    1.13    TypeRawPtr::NOTNULL= TypeRawPtr::make( TypePtr::NotNull );
    1.14  
    1.15 -  mreg2type[Op_Node] = Type::BOTTOM;
    1.16 -  mreg2type[Op_Set ] = 0;
    1.17 -  mreg2type[Op_RegI] = TypeInt::INT;
    1.18 -  mreg2type[Op_RegP] = TypePtr::BOTTOM;
    1.19 -  mreg2type[Op_RegF] = Type::FLOAT;
    1.20 -  mreg2type[Op_RegD] = Type::DOUBLE;
    1.21 -  mreg2type[Op_RegL] = TypeLong::LONG;
    1.22 -  mreg2type[Op_RegFlags] = TypeInt::CC;
    1.23 -
    1.24    const Type **fmembar = TypeTuple::fields(0);
    1.25    TypeTuple::MEMBAR = TypeTuple::make(TypeFunc::Parms+0, fmembar);
    1.26  
    1.27 @@ -305,6 +297,19 @@
    1.28                                             false, 0, oopDesc::klass_offset_in_bytes());
    1.29    TypeOopPtr::BOTTOM  = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot);
    1.30  
    1.31 +  TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR );
    1.32 +  TypeNarrowOop::BOTTOM   = TypeNarrowOop::make( TypeInstPtr::BOTTOM );
    1.33 +
    1.34 +  mreg2type[Op_Node] = Type::BOTTOM;
    1.35 +  mreg2type[Op_Set ] = 0;
    1.36 +  mreg2type[Op_RegN] = TypeNarrowOop::BOTTOM;
    1.37 +  mreg2type[Op_RegI] = TypeInt::INT;
    1.38 +  mreg2type[Op_RegP] = TypePtr::BOTTOM;
    1.39 +  mreg2type[Op_RegF] = Type::FLOAT;
    1.40 +  mreg2type[Op_RegD] = Type::DOUBLE;
    1.41 +  mreg2type[Op_RegL] = TypeLong::LONG;
    1.42 +  mreg2type[Op_RegFlags] = TypeInt::CC;
    1.43 +
    1.44    TypeAryPtr::RANGE   = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), current->env()->Object_klass(), false, arrayOopDesc::length_offset_in_bytes());
    1.45    // There is no shared klass for Object[].  See note in TypeAryPtr::klass().
    1.46    TypeAryPtr::OOPS    = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInstPtr::BOTTOM,TypeInt::POS), NULL /*ciArrayKlass::make(o)*/,  false,  Type::OffsetBot);
    1.47 @@ -316,6 +321,7 @@
    1.48    TypeAryPtr::FLOATS  = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::FLOAT        ,TypeInt::POS), ciTypeArrayKlass::make(T_FLOAT),  true,  Type::OffsetBot);
    1.49    TypeAryPtr::DOUBLES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::DOUBLE       ,TypeInt::POS), ciTypeArrayKlass::make(T_DOUBLE), true,  Type::OffsetBot);
    1.50  
    1.51 +  TypeAryPtr::_array_body_type[T_NARROWOOP] = NULL; // what should this be?
    1.52    TypeAryPtr::_array_body_type[T_OBJECT]  = TypeAryPtr::OOPS;
    1.53    TypeAryPtr::_array_body_type[T_ARRAY]   = TypeAryPtr::OOPS;   // arrays are stored in oop arrays
    1.54    TypeAryPtr::_array_body_type[T_BYTE]    = TypeAryPtr::BYTES;
    1.55 @@ -345,6 +351,7 @@
    1.56    longpair[1] = TypeLong::LONG;
    1.57    TypeTuple::LONG_PAIR = TypeTuple::make(2, longpair);
    1.58  
    1.59 +  _const_basic_type[T_NARROWOOP] = TypeNarrowOop::BOTTOM;
    1.60    _const_basic_type[T_BOOLEAN] = TypeInt::BOOL;
    1.61    _const_basic_type[T_CHAR]    = TypeInt::CHAR;
    1.62    _const_basic_type[T_BYTE]    = TypeInt::BYTE;
    1.63 @@ -359,6 +366,7 @@
    1.64    _const_basic_type[T_ADDRESS] = TypeRawPtr::BOTTOM;  // both interpreter return addresses & random raw ptrs
    1.65    _const_basic_type[T_CONFLICT]= Type::BOTTOM;        // why not?
    1.66  
    1.67 +  _zero_type[T_NARROWOOP] = TypeNarrowOop::NULL_PTR;
    1.68    _zero_type[T_BOOLEAN] = TypeInt::ZERO;     // false == 0
    1.69    _zero_type[T_CHAR]    = TypeInt::ZERO;     // '\0' == 0
    1.70    _zero_type[T_BYTE]    = TypeInt::ZERO;     // 0x00 == 0
    1.71 @@ -400,6 +408,10 @@
    1.72      Type* t = (Type*)i._value;
    1.73      tdic->Insert(t,t);  // New Type, insert into Type table
    1.74    }
    1.75 +
    1.76 +#ifdef ASSERT
    1.77 +  verify_lastype();
    1.78 +#endif
    1.79  }
    1.80  
    1.81  //------------------------------hashcons---------------------------------------
    1.82 @@ -467,7 +479,19 @@
    1.83  // Compute the MEET of two types.  NOT virtual.  It enforces that meet is
    1.84  // commutative and the lattice is symmetric.
    1.85  const Type *Type::meet( const Type *t ) const {
    1.86 +  if (isa_narrowoop() && t->isa_narrowoop()) {
    1.87 +    const Type* result = is_narrowoop()->make_oopptr()->meet(t->is_narrowoop()->make_oopptr());
    1.88 +    if (result->isa_oopptr()) {
    1.89 +      return result->isa_oopptr()->make_narrowoop();
    1.90 +    } else if (result == TypePtr::NULL_PTR) {
    1.91 +      return TypeNarrowOop::NULL_PTR;
    1.92 +    } else {
    1.93 +      return result;
    1.94 +    }
    1.95 +  }
    1.96 +
    1.97    const Type *mt = xmeet(t);
    1.98 +  if (isa_narrowoop() || t->isa_narrowoop()) return mt;
    1.99  #ifdef ASSERT
   1.100    assert( mt == t->xmeet(this), "meet not commutative" );
   1.101    const Type* dual_join = mt->_dual;
   1.102 @@ -556,6 +580,9 @@
   1.103    case AryPtr:
   1.104      return t->xmeet(this);
   1.105  
   1.106 +  case NarrowOop:
   1.107 +    return t->xmeet(this);
   1.108 +
   1.109    case Bad:                     // Type check
   1.110    default:                      // Bogus type not in lattice
   1.111      typerr(t);
   1.112 @@ -613,6 +640,7 @@
   1.113    Bad,          // Int - handled in v-call
   1.114    Bad,          // Long - handled in v-call
   1.115    Half,         // Half
   1.116 +  Bad,          // NarrowOop - handled in v-call
   1.117  
   1.118    Bad,          // Tuple - handled in v-call
   1.119    Bad,          // Array - handled in v-call
   1.120 @@ -668,11 +696,14 @@
   1.121    ResourceMark rm;
   1.122    Dict d(cmpkey,hashkey);       // Stop recursive type dumping
   1.123    dump2(d,1, st);
   1.124 +  if (isa_ptr() && is_ptr()->is_narrow()) {
   1.125 +    st->print(" [narrow]");
   1.126 +  }
   1.127  }
   1.128  
   1.129  //------------------------------data-------------------------------------------
   1.130  const char * const Type::msg[Type::lastype] = {
   1.131 -  "bad","control","top","int:","long:","half",
   1.132 +  "bad","control","top","int:","long:","half", "narrowoop:",
   1.133    "tuple:", "aryptr",
   1.134    "anyptr:", "rawptr:", "java:", "inst:", "ary:", "klass:",
   1.135    "func", "abIO", "return_address", "memory",
   1.136 @@ -735,7 +766,7 @@
   1.137  //------------------------------isa_oop_ptr------------------------------------
   1.138  // Return true if type is an oop pointer type.  False for raw pointers.
   1.139  static char isa_oop_ptr_tbl[Type::lastype] = {
   1.140 -  0,0,0,0,0,0,0/*tuple*/, 0/*ary*/,
   1.141 +  0,0,0,0,0,0,0/*narrowoop*/,0/*tuple*/, 0/*ary*/,
   1.142    0/*anyptr*/,0/*rawptr*/,1/*OopPtr*/,1/*InstPtr*/,1/*AryPtr*/,1/*KlassPtr*/,
   1.143    0/*func*/,0,0/*return_address*/,0,
   1.144    /*floats*/0,0,0, /*doubles*/0,0,0,
   1.145 @@ -1051,6 +1082,7 @@
   1.146    case DoubleTop:
   1.147    case DoubleCon:
   1.148    case DoubleBot:
   1.149 +  case NarrowOop:
   1.150    case Bottom:                  // Ye Olde Default
   1.151      return Type::BOTTOM;
   1.152    default:                      // All else is a mistake
   1.153 @@ -1718,6 +1750,9 @@
   1.154  
   1.155  //------------------------------make-------------------------------------------
   1.156  const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) {
   1.157 +  if (UseCompressedOops && elem->isa_oopptr()) {
   1.158 +    elem = elem->is_oopptr()->make_narrowoop();
   1.159 +  }
   1.160    size = normalize_array_size(size);
   1.161    return (TypeAry*)(new TypeAry(elem,size))->hashcons();
   1.162  }
   1.163 @@ -1800,14 +1835,28 @@
   1.164    // In such cases, an array built on this ary must have no subclasses.
   1.165    if (_elem == BOTTOM)      return false;  // general array not exact
   1.166    if (_elem == TOP   )      return false;  // inverted general array not exact
   1.167 -  const TypeOopPtr*  toop = _elem->isa_oopptr();
   1.168 +  const TypeOopPtr*  toop = NULL;
   1.169 +  if (UseCompressedOops) {
   1.170 +    const TypeNarrowOop* noop = _elem->isa_narrowoop();
   1.171 +    if (noop) toop = noop->make_oopptr()->isa_oopptr();
   1.172 +  } else {
   1.173 +    toop = _elem->isa_oopptr();
   1.174 +  }
   1.175    if (!toop)                return true;   // a primitive type, like int
   1.176    ciKlass* tklass = toop->klass();
   1.177    if (tklass == NULL)       return false;  // unloaded class
   1.178    if (!tklass->is_loaded()) return false;  // unloaded class
   1.179 -  const TypeInstPtr* tinst = _elem->isa_instptr();
   1.180 +  const TypeInstPtr* tinst;
   1.181 +  if (_elem->isa_narrowoop())
   1.182 +    tinst = _elem->is_narrowoop()->make_oopptr()->isa_instptr();
   1.183 +  else
   1.184 +    tinst = _elem->isa_instptr();
   1.185    if (tinst)                return tklass->as_instance_klass()->is_final();
   1.186 -  const TypeAryPtr*  tap = _elem->isa_aryptr();
   1.187 +  const TypeAryPtr*  tap;
   1.188 +  if (_elem->isa_narrowoop())
   1.189 +    tap = _elem->is_narrowoop()->make_oopptr()->isa_aryptr();
   1.190 +  else
   1.191 +    tap = _elem->isa_aryptr();
   1.192    if (tap)                  return tap->ary()->ary_must_be_exact();
   1.193    return false;
   1.194  }
   1.195 @@ -1864,6 +1913,7 @@
   1.196    case DoubleTop:
   1.197    case DoubleCon:
   1.198    case DoubleBot:
   1.199 +  case NarrowOop:
   1.200    case Bottom:                  // Ye Olde Default
   1.201      return Type::BOTTOM;
   1.202    case Top:
   1.203 @@ -2455,6 +2505,10 @@
   1.204    return make( _ptr, xadd_offset(offset) );
   1.205  }
   1.206  
   1.207 +const TypeNarrowOop* TypeOopPtr::make_narrowoop() const {
   1.208 +  return TypeNarrowOop::make(this);
   1.209 +}
   1.210 +
   1.211  int TypeOopPtr::meet_instance(int iid) const {
   1.212    if (iid == 0) {
   1.213      return (_instance_id < 0)  ? _instance_id : UNKNOWN_INSTANCE;
   1.214 @@ -2607,6 +2661,7 @@
   1.215    case DoubleTop:
   1.216    case DoubleCon:
   1.217    case DoubleBot:
   1.218 +  case NarrowOop:
   1.219    case Bottom:                  // Ye Olde Default
   1.220      return Type::BOTTOM;
   1.221    case Top:
   1.222 @@ -3021,6 +3076,9 @@
   1.223    jint res = cache;
   1.224    if (res == 0) {
   1.225      switch (etype) {
   1.226 +    case T_NARROWOOP:
   1.227 +      etype = T_OBJECT;
   1.228 +      break;
   1.229      case T_CONFLICT:
   1.230      case T_ILLEGAL:
   1.231      case T_VOID:
   1.232 @@ -3093,6 +3151,7 @@
   1.233    case DoubleTop:
   1.234    case DoubleCon:
   1.235    case DoubleBot:
   1.236 +  case NarrowOop:
   1.237    case Bottom:                  // Ye Olde Default
   1.238      return Type::BOTTOM;
   1.239    case Top:
   1.240 @@ -3293,6 +3352,124 @@
   1.241  
   1.242  
   1.243  //=============================================================================
   1.244 +const TypeNarrowOop *TypeNarrowOop::BOTTOM;
   1.245 +const TypeNarrowOop *TypeNarrowOop::NULL_PTR;
   1.246 +
   1.247 +
   1.248 +const TypeNarrowOop* TypeNarrowOop::make(const TypePtr* type) {
   1.249 +  return (const TypeNarrowOop*)(new TypeNarrowOop(type))->hashcons();
   1.250 +}
   1.251 +
   1.252 +//------------------------------hash-------------------------------------------
   1.253 +// Type-specific hashing function.
   1.254 +int TypeNarrowOop::hash(void) const {
   1.255 +  return _ooptype->hash() + 7;
   1.256 +}
   1.257 +
   1.258 +
   1.259 +bool TypeNarrowOop::eq( const Type *t ) const {
   1.260 +  const TypeNarrowOop* tc = t->isa_narrowoop();
   1.261 +  if (tc != NULL) {
   1.262 +    if (_ooptype->base() != tc->_ooptype->base()) {
   1.263 +      return false;
   1.264 +    }
   1.265 +    return tc->_ooptype->eq(_ooptype);
   1.266 +  }
   1.267 +  return false;
   1.268 +}
   1.269 +
   1.270 +bool TypeNarrowOop::singleton(void) const {    // TRUE if type is a singleton
   1.271 +  return _ooptype->singleton();
   1.272 +}
   1.273 +
   1.274 +bool TypeNarrowOop::empty(void) const {
   1.275 +  return _ooptype->empty();
   1.276 +}
   1.277 +
   1.278 +//------------------------------meet-------------------------------------------
   1.279 +// Compute the MEET of two types.  It returns a new Type object.
   1.280 +const Type *TypeNarrowOop::xmeet( const Type *t ) const {
   1.281 +  // Perform a fast test for common case; meeting the same types together.
   1.282 +  if( this == t ) return this;  // Meeting same type-rep?
   1.283 +
   1.284 +
   1.285 +  // Current "this->_base" is OopPtr
   1.286 +  switch (t->base()) {          // switch on original type
   1.287 +
   1.288 +  case Int:                     // Mixing ints & oops happens when javac
   1.289 +  case Long:                    // reuses local variables
   1.290 +  case FloatTop:
   1.291 +  case FloatCon:
   1.292 +  case FloatBot:
   1.293 +  case DoubleTop:
   1.294 +  case DoubleCon:
   1.295 +  case DoubleBot:
   1.296 +  case Bottom:                  // Ye Olde Default
   1.297 +    return Type::BOTTOM;
   1.298 +  case Top:
   1.299 +    return this;
   1.300 +
   1.301 +  case NarrowOop: {
   1.302 +    const Type* result = _ooptype->xmeet(t->is_narrowoop()->make_oopptr());
   1.303 +    if (result->isa_ptr()) {
   1.304 +      return TypeNarrowOop::make(result->is_ptr());
   1.305 +    }
   1.306 +    return result;
   1.307 +  }
   1.308 +
   1.309 +  default:                      // All else is a mistake
   1.310 +    typerr(t);
   1.311 +
   1.312 +  case RawPtr:
   1.313 +  case AnyPtr:
   1.314 +  case OopPtr:
   1.315 +  case InstPtr:
   1.316 +  case KlassPtr:
   1.317 +  case AryPtr:
   1.318 +    typerr(t);
   1.319 +    return Type::BOTTOM;
   1.320 +
   1.321 +  } // End of switch
   1.322 +}
   1.323 +
   1.324 +const Type *TypeNarrowOop::xdual() const {    // Compute dual right now.
   1.325 +  const TypePtr* odual = _ooptype->dual()->is_ptr();
   1.326 +  return new TypeNarrowOop(odual);
   1.327 +}
   1.328 +
   1.329 +const Type *TypeNarrowOop::filter( const Type *kills ) const {
   1.330 +  if (kills->isa_narrowoop()) {
   1.331 +    const Type* ft =_ooptype->filter(kills->is_narrowoop()->_ooptype);
   1.332 +    if (ft->empty())
   1.333 +      return Type::TOP;           // Canonical empty value
   1.334 +    if (ft->isa_ptr()) {
   1.335 +      return make(ft->isa_ptr());
   1.336 +    }
   1.337 +    return ft;
   1.338 +  } else if (kills->isa_ptr()) {
   1.339 +    const Type* ft = _ooptype->join(kills);
   1.340 +    if (ft->empty())
   1.341 +      return Type::TOP;           // Canonical empty value
   1.342 +    return ft;
   1.343 +  } else {
   1.344 +    return Type::TOP;
   1.345 +  }
   1.346 +}
   1.347 +
   1.348 +
   1.349 +intptr_t TypeNarrowOop::get_con() const {
   1.350 +  return _ooptype->get_con();
   1.351 +}
   1.352 +
   1.353 +#ifndef PRODUCT
   1.354 +void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const {
   1.355 +  tty->print("narrowoop: ");
   1.356 +  _ooptype->dump2(d, depth, st);
   1.357 +}
   1.358 +#endif
   1.359 +
   1.360 +
   1.361 +//=============================================================================
   1.362  // Convenience common pre-built types.
   1.363  
   1.364  // Not-null object klass or below
   1.365 @@ -3341,28 +3518,33 @@
   1.366    ciKlass* k_ary = NULL;
   1.367    const TypeInstPtr *tinst;
   1.368    const TypeAryPtr *tary;
   1.369 +  const Type* el = elem();
   1.370 +  if (el->isa_narrowoop()) {
   1.371 +    el = el->is_narrowoop()->make_oopptr();
   1.372 +  }
   1.373 +
   1.374    // Get element klass
   1.375 -  if ((tinst = elem()->isa_instptr()) != NULL) {
   1.376 +  if ((tinst = el->isa_instptr()) != NULL) {
   1.377      // Compute array klass from element klass
   1.378      k_ary = ciObjArrayKlass::make(tinst->klass());
   1.379 -  } else if ((tary = elem()->isa_aryptr()) != NULL) {
   1.380 +  } else if ((tary = el->isa_aryptr()) != NULL) {
   1.381      // Compute array klass from element klass
   1.382      ciKlass* k_elem = tary->klass();
   1.383      // If element type is something like bottom[], k_elem will be null.
   1.384      if (k_elem != NULL)
   1.385        k_ary = ciObjArrayKlass::make(k_elem);
   1.386 -  } else if ((elem()->base() == Type::Top) ||
   1.387 -             (elem()->base() == Type::Bottom)) {
   1.388 +  } else if ((el->base() == Type::Top) ||
   1.389 +             (el->base() == Type::Bottom)) {
   1.390      // element type of Bottom occurs from meet of basic type
   1.391      // and object; Top occurs when doing join on Bottom.
   1.392      // Leave k_ary at NULL.
   1.393    } else {
   1.394      // Cannot compute array klass directly from basic type,
   1.395      // since subtypes of TypeInt all have basic type T_INT.
   1.396 -    assert(!elem()->isa_int(),
   1.397 +    assert(!el->isa_int(),
   1.398             "integral arrays must be pre-equipped with a class");
   1.399      // Compute array klass directly from basic type
   1.400 -    k_ary = ciTypeArrayKlass::make(elem()->basic_type());
   1.401 +    k_ary = ciTypeArrayKlass::make(el->basic_type());
   1.402    }
   1.403  
   1.404    if( this != TypeAryPtr::OOPS )
   1.405 @@ -3710,7 +3892,7 @@
   1.406  //------------------------------print_flattened--------------------------------
   1.407  // Print a 'flattened' signature
   1.408  static const char * const flat_type_msg[Type::lastype] = {
   1.409 -  "bad","control","top","int","long","_",
   1.410 +  "bad","control","top","int","long","_", "narrowoop",
   1.411    "tuple:", "array:",
   1.412    "ptr", "rawptr", "ptr", "ptr", "ptr", "ptr",
   1.413    "func", "abIO", "return_address", "mem",

mercurial