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