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