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