1 /*
   2  * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 // type hierarchy
  26 class ValueType;
  27 class   VoidType;
  28 class   IntType;
  29 class     IntConstant;
  30 class     IntInterval;
  31 class   LongType;
  32 class     LongConstant;
  33 class   FloatType;
  34 class     FloatConstant;
  35 class   DoubleType;
  36 class     DoubleConstant;
  37 class   ObjectType;
  38 class     ObjectConstant;
  39 class     ArrayType;
  40 class       ArrayConstant;
  41 class     InstanceType;
  42 class       InstanceConstant;
  43 class     ClassType;
  44 class       ClassConstant;
  45 class   AddressType;
  46 class     AddressConstant;
  47 class   IllegalType;
  48 
  49 
  50 // predefined types
  51 extern VoidType*       voidType;
  52 extern IntType*        intType;
  53 extern LongType*       longType;
  54 extern FloatType*      floatType;
  55 extern DoubleType*     doubleType;
  56 extern ObjectType*     objectType;
  57 extern ArrayType*      arrayType;
  58 extern InstanceType*   instanceType;
  59 extern ClassType*      classType;
  60 extern AddressType*    addressType;
  61 extern IllegalType*    illegalType;
  62 
  63 
  64 // predefined constants
  65 extern IntConstant*    intZero;
  66 extern IntConstant*    intOne;
  67 extern ObjectConstant* objectNull;
  68 
  69 
  70 // tags
  71 enum ValueTag {
  72   // all legal tags must come first
  73   intTag,
  74   longTag,
  75   floatTag,
  76   doubleTag,
  77   objectTag,
  78   addressTag,
  79   number_of_legal_tags,
  80   // all other tags must follow afterwards
  81   voidTag = number_of_legal_tags,
  82   illegalTag,
  83   number_of_tags
  84 };
  85 
  86 
  87 class ValueType: public CompilationResourceObj {
  88  private:
  89   const int _size;
  90   const ValueTag _tag;
  91   ValueType();
  92  protected:
  93   ValueType(ValueTag tag, int size): _tag(tag), _size(size) {}
  94 
  95  public:
  96   // initialization
  97   static void initialize(Arena* arena);
  98 
  99   // accessors
 100   virtual ValueType* base() const                = 0; // the 'canonical' type (e.g., intType for an IntConstant)
 101   ValueTag tag() const { return _tag; }          // the 'canonical' tag  (useful for type matching)
 102   int size() const {                             // the size of an object of the type in words
 103     assert(_size > -1, "shouldn't be asking for size");
 104     return _size;
 105   }
 106   virtual const char tchar() const               = 0; // the type 'character' for printing
 107   virtual const char* name() const               = 0; // the type name for printing
 108   virtual bool is_constant() const               { return false; }
 109 
 110   // testers
 111   bool is_void()                                 { return tag() == voidTag;   }
 112   bool is_int()                                  { return tag() == intTag;    }
 113   bool is_long()                                 { return tag() == longTag;   }
 114   bool is_float()                                { return tag() == floatTag;  }
 115   bool is_double()                               { return tag() == doubleTag; }
 116   bool is_object()                               { return as_ObjectType()   != NULL; }
 117   bool is_array()                                { return as_ArrayType()    != NULL; }
 118   bool is_instance()                             { return as_InstanceType() != NULL; }
 119   bool is_class()                                { return as_ClassType()    != NULL; }
 120   bool is_address()                              { return as_AddressType()  != NULL; }
 121   bool is_illegal()                              { return tag() == illegalTag; }
 122 
 123   bool is_int_kind() const                       { return tag() == intTag || tag() == longTag; }
 124   bool is_float_kind() const                     { return tag() == floatTag || tag() == doubleTag; }
 125   bool is_object_kind() const                    { return tag() == objectTag; }
 126 
 127   bool is_single_word() const                    { return _size == 1; }
 128   bool is_double_word() const                    { return _size == 2; }
 129 
 130   // casting
 131   virtual VoidType*         as_VoidType()        { return NULL; }
 132   virtual IntType*          as_IntType()         { return NULL; }
 133   virtual LongType*         as_LongType()        { return NULL; }
 134   virtual FloatType*        as_FloatType()       { return NULL; }
 135   virtual DoubleType*       as_DoubleType()      { return NULL; }
 136   virtual ObjectType*       as_ObjectType()      { return NULL; }
 137   virtual ArrayType*        as_ArrayType()       { return NULL; }
 138   virtual InstanceType*     as_InstanceType()    { return NULL; }
 139   virtual ClassType*        as_ClassType()       { return NULL; }
 140   virtual AddressType*      as_AddressType()     { return NULL; }
 141   virtual IllegalType*      as_IllegalType()     { return NULL; }
 142 
 143   virtual IntConstant*      as_IntConstant()     { return NULL; }
 144   virtual LongConstant*     as_LongConstant()    { return NULL; }
 145   virtual FloatConstant*    as_FloatConstant()   { return NULL; }
 146   virtual DoubleConstant*   as_DoubleConstant()  { return NULL; }
 147   virtual ObjectConstant*   as_ObjectConstant()  { return NULL; }
 148   virtual InstanceConstant* as_InstanceConstant(){ return NULL; }
 149   virtual ClassConstant*    as_ClassConstant()   { return NULL; }
 150   virtual ArrayConstant*    as_ArrayConstant()   { return NULL; }
 151   virtual AddressConstant*  as_AddressConstant() { return NULL; }
 152 
 153   // type operations
 154   ValueType* meet(ValueType* y) const;
 155   ValueType* join(ValueType* y) const;
 156 
 157   // debugging
 158   void print(outputStream* s = tty)              { s->print(name()); }
 159 };
 160 
 161 
 162 class VoidType: public ValueType {
 163  public:
 164   VoidType(): ValueType(voidTag, 0) {}
 165   virtual ValueType* base() const                { return voidType; }
 166   virtual const char tchar() const               { return 'v'; }
 167   virtual const char* name() const               { return "void"; }
 168   virtual VoidType* as_VoidType()                { return this; }
 169 };
 170 
 171 
 172 class IntType: public ValueType {
 173  public:
 174   IntType(): ValueType(intTag, 1) {}
 175   virtual ValueType* base() const                { return intType; }
 176   virtual const char tchar() const               { return 'i'; }
 177   virtual const char* name() const               { return "int"; }
 178   virtual IntType* as_IntType()                  { return this; }
 179 };
 180 
 181 
 182 class IntConstant: public IntType {
 183  private:
 184   jint _value;
 185 
 186  public:
 187   IntConstant(jint value)                        { _value = value; }
 188 
 189   jint value() const                             { return _value; }
 190 
 191   virtual bool is_constant() const               { return true; }
 192   virtual IntConstant* as_IntConstant()          { return this; }
 193 };
 194 
 195 
 196 class IntInterval: public IntType {
 197  private:
 198   jint _beg;
 199   jint _end;
 200 
 201  public:
 202   IntInterval(jint beg, jint end) {
 203     assert(beg <= end, "illegal interval");
 204     _beg = beg;
 205     _end = end;
 206   }
 207 
 208   jint beg() const                               { return _beg; }
 209   jint end() const                               { return _end; }
 210 
 211   virtual bool is_interval() const               { return true; }
 212 };
 213 
 214 
 215 class LongType: public ValueType {
 216  public:
 217   LongType(): ValueType(longTag, 2) {}
 218   virtual ValueType* base() const                { return longType; }
 219   virtual const char tchar() const               { return 'l'; }
 220   virtual const char* name() const               { return "long"; }
 221   virtual LongType* as_LongType()                { return this; }
 222 };
 223 
 224 
 225 class LongConstant: public LongType {
 226  private:
 227   jlong _value;
 228 
 229  public:
 230   LongConstant(jlong value)                      { _value = value; }
 231 
 232   jlong value() const                            { return _value; }
 233 
 234   virtual bool is_constant() const               { return true; }
 235   virtual LongConstant* as_LongConstant()        { return this; }
 236 };
 237 
 238 
 239 class FloatType: public ValueType {
 240  public:
 241   FloatType(): ValueType(floatTag, 1) {}
 242   virtual ValueType* base() const                { return floatType; }
 243   virtual const char tchar() const               { return 'f'; }
 244   virtual const char* name() const               { return "float"; }
 245   virtual FloatType* as_FloatType()              { return this; }
 246 };
 247 
 248 
 249 class FloatConstant: public FloatType {
 250  private:
 251   jfloat _value;
 252 
 253  public:
 254   FloatConstant(jfloat value)                    { _value = value; }
 255 
 256   jfloat value() const                           { return _value; }
 257 
 258   virtual bool is_constant() const               { return true; }
 259   virtual FloatConstant* as_FloatConstant()      { return this; }
 260 };
 261 
 262 
 263 class DoubleType: public ValueType {
 264  public:
 265   DoubleType(): ValueType(doubleTag, 2) {}
 266   virtual ValueType* base() const                { return doubleType; }
 267   virtual const char tchar() const               { return 'd'; }
 268   virtual const char* name() const               { return "double"; }
 269   virtual DoubleType* as_DoubleType()            { return this; }
 270 };
 271 
 272 
 273 class DoubleConstant: public DoubleType {
 274  private:
 275   jdouble _value;
 276 
 277  public:
 278   DoubleConstant(jdouble value)                  { _value = value; }
 279 
 280   jdouble value() const                          { return _value; }
 281 
 282   virtual bool is_constant() const               { return true; }
 283   virtual DoubleConstant* as_DoubleConstant()    { return this; }
 284 };
 285 
 286 
 287 class ObjectType: public ValueType {
 288  public:
 289   ObjectType(): ValueType(objectTag, 1) {}
 290   virtual ValueType* base() const                { return objectType; }
 291   virtual const char tchar() const               { return 'a'; }
 292   virtual const char* name() const               { return "object"; }
 293   virtual ObjectType* as_ObjectType()            { return this; }
 294   virtual ciObject* constant_value() const       { ShouldNotReachHere(); return NULL;  }
 295   bool is_loaded() const;
 296   jobject encoding() const;
 297 };
 298 
 299 
 300 class ObjectConstant: public ObjectType {
 301  private:
 302   ciObject* _value;
 303 
 304  public:
 305   ObjectConstant(ciObject* value)                { _value = value; }
 306 
 307   ciObject* value() const                        { return _value; }
 308 
 309   virtual bool is_constant() const               { return true; }
 310   virtual ObjectConstant* as_ObjectConstant()    { return this; }
 311   virtual ciObject* constant_value() const;
 312 };
 313 
 314 
 315 class ArrayType: public ObjectType {
 316  public:
 317   virtual ArrayType* as_ArrayType()              { return this; }
 318 };
 319 
 320 
 321 class ArrayConstant: public ArrayType {
 322  private:
 323   ciArray* _value;
 324 
 325  public:
 326   ArrayConstant(ciArray* value)                  { _value = value; }
 327 
 328   ciArray* value() const                         { return _value; }
 329 
 330   virtual bool is_constant() const               { return true; }
 331 
 332   virtual ArrayConstant* as_ArrayConstant()      { return this; }
 333   virtual ciObject* constant_value() const;
 334 };
 335 
 336 
 337 class InstanceType: public ObjectType {
 338  public:
 339   virtual InstanceType* as_InstanceType()        { return this; }
 340 };
 341 
 342 
 343 class InstanceConstant: public InstanceType {
 344  private:
 345   ciInstance* _value;
 346 
 347  public:
 348   InstanceConstant(ciInstance* value)            { _value = value; }
 349 
 350   ciInstance* value() const                      { return _value; }
 351 
 352   virtual bool is_constant() const               { return true; }
 353 
 354   virtual InstanceConstant* as_InstanceConstant(){ return this; }
 355   virtual ciObject* constant_value() const;
 356 };
 357 
 358 
 359 class ClassType: public ObjectType {
 360  public:
 361   virtual ClassType* as_ClassType()              { return this; }
 362 };
 363 
 364 
 365 class ClassConstant: public ClassType {
 366  private:
 367   ciInstanceKlass* _value;
 368 
 369  public:
 370   ClassConstant(ciInstanceKlass* value)          { _value = value; }
 371 
 372   ciInstanceKlass* value() const                 { return _value; }
 373 
 374   virtual bool is_constant() const               { return true; }
 375 
 376   virtual ClassConstant* as_ClassConstant()      { return this; }
 377   virtual ciObject* constant_value() const;
 378 };
 379 
 380 
 381 class AddressType: public ValueType {
 382  public:
 383   AddressType(): ValueType(addressTag, 1) {}
 384   virtual ValueType* base() const                { return addressType; }
 385   virtual const char tchar() const               { return 'r'; }
 386   virtual const char* name() const               { return "address"; }
 387   virtual AddressType* as_AddressType()          { return this; }
 388 };
 389 
 390 
 391 class AddressConstant: public AddressType {
 392  private:
 393   jint _value;
 394 
 395  public:
 396   AddressConstant(jint value)                    { _value = value; }
 397 
 398   jint value() const                             { return _value; }
 399 
 400   virtual bool is_constant() const               { return true; }
 401 
 402   virtual AddressConstant* as_AddressConstant()  { return this; }
 403 };
 404 
 405 
 406 class IllegalType: public ValueType {
 407  public:
 408   IllegalType(): ValueType(illegalTag, -1) {}
 409   virtual ValueType* base() const                { return illegalType; }
 410   virtual const char tchar() const               { return ' '; }
 411   virtual const char* name() const               { return "illegal"; }
 412   virtual IllegalType* as_IllegalType()          { return this; }
 413 };
 414 
 415 
 416 // conversion between ValueTypes, BasicTypes, and ciConstants
 417 ValueType* as_ValueType(BasicType type);
 418 ValueType* as_ValueType(ciConstant value);
 419 BasicType  as_BasicType(ValueType* type);
 420 
 421 inline ValueType* as_ValueType(ciType* type) { return as_ValueType(type->basic_type()); }