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