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