Tue, 09 Mar 2010 20:16:19 +0100
6919934: JSR 292 needs to support x86 C1
Summary: This implements JSR 292 support for C1 x86.
Reviewed-by: never, jrose, kvn
duke@435 | 1 | /* |
duke@435 | 2 | * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
duke@435 | 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
duke@435 | 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
duke@435 | 21 | * have any questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
duke@435 | 25 | // type hierarchy |
duke@435 | 26 | class ValueType; |
duke@435 | 27 | class VoidType; |
duke@435 | 28 | class IntType; |
duke@435 | 29 | class IntConstant; |
duke@435 | 30 | class IntInterval; |
duke@435 | 31 | class LongType; |
duke@435 | 32 | class LongConstant; |
duke@435 | 33 | class FloatType; |
duke@435 | 34 | class FloatConstant; |
duke@435 | 35 | class DoubleType; |
duke@435 | 36 | class DoubleConstant; |
duke@435 | 37 | class ObjectType; |
duke@435 | 38 | class ObjectConstant; |
duke@435 | 39 | class ArrayType; |
duke@435 | 40 | class ArrayConstant; |
duke@435 | 41 | class InstanceType; |
duke@435 | 42 | class InstanceConstant; |
duke@435 | 43 | class ClassType; |
duke@435 | 44 | class ClassConstant; |
duke@435 | 45 | class AddressType; |
duke@435 | 46 | class AddressConstant; |
duke@435 | 47 | class IllegalType; |
duke@435 | 48 | |
duke@435 | 49 | |
duke@435 | 50 | // predefined types |
duke@435 | 51 | extern VoidType* voidType; |
duke@435 | 52 | extern IntType* intType; |
duke@435 | 53 | extern LongType* longType; |
duke@435 | 54 | extern FloatType* floatType; |
duke@435 | 55 | extern DoubleType* doubleType; |
duke@435 | 56 | extern ObjectType* objectType; |
duke@435 | 57 | extern ArrayType* arrayType; |
duke@435 | 58 | extern InstanceType* instanceType; |
duke@435 | 59 | extern ClassType* classType; |
duke@435 | 60 | extern AddressType* addressType; |
duke@435 | 61 | extern IllegalType* illegalType; |
duke@435 | 62 | |
duke@435 | 63 | |
duke@435 | 64 | // predefined constants |
duke@435 | 65 | extern IntConstant* intZero; |
duke@435 | 66 | extern IntConstant* intOne; |
duke@435 | 67 | extern ObjectConstant* objectNull; |
duke@435 | 68 | |
duke@435 | 69 | |
duke@435 | 70 | // tags |
duke@435 | 71 | enum ValueTag { |
duke@435 | 72 | // all legal tags must come first |
duke@435 | 73 | intTag, |
duke@435 | 74 | longTag, |
duke@435 | 75 | floatTag, |
duke@435 | 76 | doubleTag, |
duke@435 | 77 | objectTag, |
duke@435 | 78 | addressTag, |
duke@435 | 79 | number_of_legal_tags, |
duke@435 | 80 | // all other tags must follow afterwards |
duke@435 | 81 | voidTag = number_of_legal_tags, |
duke@435 | 82 | illegalTag, |
duke@435 | 83 | number_of_tags |
duke@435 | 84 | }; |
duke@435 | 85 | |
duke@435 | 86 | |
duke@435 | 87 | class ValueType: public CompilationResourceObj { |
duke@435 | 88 | private: |
duke@435 | 89 | const int _size; |
duke@435 | 90 | const ValueTag _tag; |
duke@435 | 91 | ValueType(); |
duke@435 | 92 | protected: |
duke@435 | 93 | ValueType(ValueTag tag, int size): _tag(tag), _size(size) {} |
duke@435 | 94 | |
duke@435 | 95 | public: |
duke@435 | 96 | // initialization |
duke@435 | 97 | static void initialize(); |
duke@435 | 98 | |
duke@435 | 99 | // accessors |
duke@435 | 100 | virtual ValueType* base() const = 0; // the 'canonical' type (e.g., intType for an IntConstant) |
duke@435 | 101 | ValueTag tag() const { return _tag; } // the 'canonical' tag (useful for type matching) |
duke@435 | 102 | int size() const { // the size of an object of the type in words |
duke@435 | 103 | assert(_size > -1, "shouldn't be asking for size"); |
duke@435 | 104 | return _size; |
duke@435 | 105 | } |
duke@435 | 106 | virtual const char tchar() const = 0; // the type 'character' for printing |
duke@435 | 107 | virtual const char* name() const = 0; // the type name for printing |
duke@435 | 108 | virtual bool is_constant() const { return false; } |
duke@435 | 109 | |
duke@435 | 110 | // testers |
duke@435 | 111 | bool is_void() { return tag() == voidTag; } |
duke@435 | 112 | bool is_int() { return tag() == intTag; } |
duke@435 | 113 | bool is_long() { return tag() == longTag; } |
duke@435 | 114 | bool is_float() { return tag() == floatTag; } |
duke@435 | 115 | bool is_double() { return tag() == doubleTag; } |
duke@435 | 116 | bool is_object() { return as_ObjectType() != NULL; } |
duke@435 | 117 | bool is_array() { return as_ArrayType() != NULL; } |
duke@435 | 118 | bool is_instance() { return as_InstanceType() != NULL; } |
duke@435 | 119 | bool is_class() { return as_ClassType() != NULL; } |
duke@435 | 120 | bool is_address() { return as_AddressType() != NULL; } |
duke@435 | 121 | bool is_illegal() { return tag() == illegalTag; } |
duke@435 | 122 | |
duke@435 | 123 | bool is_int_kind() const { return tag() == intTag || tag() == longTag; } |
duke@435 | 124 | bool is_float_kind() const { return tag() == floatTag || tag() == doubleTag; } |
duke@435 | 125 | bool is_object_kind() const { return tag() == objectTag; } |
duke@435 | 126 | |
duke@435 | 127 | bool is_single_word() const { return _size == 1; } |
duke@435 | 128 | bool is_double_word() const { return _size == 2; } |
duke@435 | 129 | |
duke@435 | 130 | // casting |
duke@435 | 131 | virtual VoidType* as_VoidType() { return NULL; } |
duke@435 | 132 | virtual IntType* as_IntType() { return NULL; } |
duke@435 | 133 | virtual LongType* as_LongType() { return NULL; } |
duke@435 | 134 | virtual FloatType* as_FloatType() { return NULL; } |
duke@435 | 135 | virtual DoubleType* as_DoubleType() { return NULL; } |
duke@435 | 136 | virtual ObjectType* as_ObjectType() { return NULL; } |
duke@435 | 137 | virtual ArrayType* as_ArrayType() { return NULL; } |
duke@435 | 138 | virtual InstanceType* as_InstanceType() { return NULL; } |
duke@435 | 139 | virtual ClassType* as_ClassType() { return NULL; } |
duke@435 | 140 | virtual AddressType* as_AddressType() { return NULL; } |
duke@435 | 141 | virtual IllegalType* as_IllegalType() { return NULL; } |
duke@435 | 142 | |
duke@435 | 143 | virtual IntConstant* as_IntConstant() { return NULL; } |
duke@435 | 144 | virtual LongConstant* as_LongConstant() { return NULL; } |
duke@435 | 145 | virtual FloatConstant* as_FloatConstant() { return NULL; } |
duke@435 | 146 | virtual DoubleConstant* as_DoubleConstant() { return NULL; } |
duke@435 | 147 | virtual ObjectConstant* as_ObjectConstant() { return NULL; } |
duke@435 | 148 | virtual InstanceConstant* as_InstanceConstant(){ return NULL; } |
duke@435 | 149 | virtual ClassConstant* as_ClassConstant() { return NULL; } |
duke@435 | 150 | virtual ArrayConstant* as_ArrayConstant() { return NULL; } |
duke@435 | 151 | virtual AddressConstant* as_AddressConstant() { return NULL; } |
duke@435 | 152 | |
duke@435 | 153 | // type operations |
duke@435 | 154 | ValueType* meet(ValueType* y) const; |
duke@435 | 155 | ValueType* join(ValueType* y) const; |
duke@435 | 156 | |
duke@435 | 157 | // debugging |
duke@435 | 158 | void print(outputStream* s = tty) { s->print(name()); } |
duke@435 | 159 | }; |
duke@435 | 160 | |
duke@435 | 161 | |
duke@435 | 162 | class VoidType: public ValueType { |
duke@435 | 163 | public: |
duke@435 | 164 | VoidType(): ValueType(voidTag, 0) {} |
duke@435 | 165 | virtual ValueType* base() const { return voidType; } |
duke@435 | 166 | virtual const char tchar() const { return 'v'; } |
duke@435 | 167 | virtual const char* name() const { return "void"; } |
duke@435 | 168 | virtual VoidType* as_VoidType() { return this; } |
duke@435 | 169 | }; |
duke@435 | 170 | |
duke@435 | 171 | |
duke@435 | 172 | class IntType: public ValueType { |
duke@435 | 173 | public: |
duke@435 | 174 | IntType(): ValueType(intTag, 1) {} |
duke@435 | 175 | virtual ValueType* base() const { return intType; } |
duke@435 | 176 | virtual const char tchar() const { return 'i'; } |
duke@435 | 177 | virtual const char* name() const { return "int"; } |
duke@435 | 178 | virtual IntType* as_IntType() { return this; } |
duke@435 | 179 | }; |
duke@435 | 180 | |
duke@435 | 181 | |
duke@435 | 182 | class IntConstant: public IntType { |
duke@435 | 183 | private: |
duke@435 | 184 | jint _value; |
duke@435 | 185 | |
duke@435 | 186 | public: |
duke@435 | 187 | IntConstant(jint value) { _value = value; } |
duke@435 | 188 | |
duke@435 | 189 | jint value() const { return _value; } |
duke@435 | 190 | |
duke@435 | 191 | virtual bool is_constant() const { return true; } |
duke@435 | 192 | virtual IntConstant* as_IntConstant() { return this; } |
duke@435 | 193 | }; |
duke@435 | 194 | |
duke@435 | 195 | |
duke@435 | 196 | class IntInterval: public IntType { |
duke@435 | 197 | private: |
duke@435 | 198 | jint _beg; |
duke@435 | 199 | jint _end; |
duke@435 | 200 | |
duke@435 | 201 | public: |
duke@435 | 202 | IntInterval(jint beg, jint end) { |
duke@435 | 203 | assert(beg <= end, "illegal interval"); |
duke@435 | 204 | _beg = beg; |
duke@435 | 205 | _end = end; |
duke@435 | 206 | } |
duke@435 | 207 | |
duke@435 | 208 | jint beg() const { return _beg; } |
duke@435 | 209 | jint end() const { return _end; } |
duke@435 | 210 | |
duke@435 | 211 | virtual bool is_interval() const { return true; } |
duke@435 | 212 | }; |
duke@435 | 213 | |
duke@435 | 214 | |
duke@435 | 215 | class LongType: public ValueType { |
duke@435 | 216 | public: |
duke@435 | 217 | LongType(): ValueType(longTag, 2) {} |
duke@435 | 218 | virtual ValueType* base() const { return longType; } |
duke@435 | 219 | virtual const char tchar() const { return 'l'; } |
duke@435 | 220 | virtual const char* name() const { return "long"; } |
duke@435 | 221 | virtual LongType* as_LongType() { return this; } |
duke@435 | 222 | }; |
duke@435 | 223 | |
duke@435 | 224 | |
duke@435 | 225 | class LongConstant: public LongType { |
duke@435 | 226 | private: |
duke@435 | 227 | jlong _value; |
duke@435 | 228 | |
duke@435 | 229 | public: |
duke@435 | 230 | LongConstant(jlong value) { _value = value; } |
duke@435 | 231 | |
duke@435 | 232 | jlong value() const { return _value; } |
duke@435 | 233 | |
duke@435 | 234 | virtual bool is_constant() const { return true; } |
duke@435 | 235 | virtual LongConstant* as_LongConstant() { return this; } |
duke@435 | 236 | }; |
duke@435 | 237 | |
duke@435 | 238 | |
duke@435 | 239 | class FloatType: public ValueType { |
duke@435 | 240 | public: |
duke@435 | 241 | FloatType(): ValueType(floatTag, 1) {} |
duke@435 | 242 | virtual ValueType* base() const { return floatType; } |
duke@435 | 243 | virtual const char tchar() const { return 'f'; } |
duke@435 | 244 | virtual const char* name() const { return "float"; } |
duke@435 | 245 | virtual FloatType* as_FloatType() { return this; } |
duke@435 | 246 | }; |
duke@435 | 247 | |
duke@435 | 248 | |
duke@435 | 249 | class FloatConstant: public FloatType { |
duke@435 | 250 | private: |
duke@435 | 251 | jfloat _value; |
duke@435 | 252 | |
duke@435 | 253 | public: |
duke@435 | 254 | FloatConstant(jfloat value) { _value = value; } |
duke@435 | 255 | |
duke@435 | 256 | jfloat value() const { return _value; } |
duke@435 | 257 | |
duke@435 | 258 | virtual bool is_constant() const { return true; } |
duke@435 | 259 | virtual FloatConstant* as_FloatConstant() { return this; } |
duke@435 | 260 | }; |
duke@435 | 261 | |
duke@435 | 262 | |
duke@435 | 263 | class DoubleType: public ValueType { |
duke@435 | 264 | public: |
duke@435 | 265 | DoubleType(): ValueType(doubleTag, 2) {} |
duke@435 | 266 | virtual ValueType* base() const { return doubleType; } |
duke@435 | 267 | virtual const char tchar() const { return 'd'; } |
duke@435 | 268 | virtual const char* name() const { return "double"; } |
duke@435 | 269 | virtual DoubleType* as_DoubleType() { return this; } |
duke@435 | 270 | }; |
duke@435 | 271 | |
duke@435 | 272 | |
duke@435 | 273 | class DoubleConstant: public DoubleType { |
duke@435 | 274 | private: |
duke@435 | 275 | jdouble _value; |
duke@435 | 276 | |
duke@435 | 277 | public: |
duke@435 | 278 | DoubleConstant(jdouble value) { _value = value; } |
duke@435 | 279 | |
duke@435 | 280 | jdouble value() const { return _value; } |
duke@435 | 281 | |
duke@435 | 282 | virtual bool is_constant() const { return true; } |
duke@435 | 283 | virtual DoubleConstant* as_DoubleConstant() { return this; } |
duke@435 | 284 | }; |
duke@435 | 285 | |
duke@435 | 286 | |
duke@435 | 287 | class ObjectType: public ValueType { |
duke@435 | 288 | public: |
duke@435 | 289 | ObjectType(): ValueType(objectTag, 1) {} |
duke@435 | 290 | virtual ValueType* base() const { return objectType; } |
duke@435 | 291 | virtual const char tchar() const { return 'a'; } |
duke@435 | 292 | virtual const char* name() const { return "object"; } |
duke@435 | 293 | virtual ObjectType* as_ObjectType() { return this; } |
duke@435 | 294 | virtual ciObject* constant_value() const { ShouldNotReachHere(); return NULL; } |
duke@435 | 295 | bool is_loaded() const; |
duke@435 | 296 | jobject encoding() const; |
duke@435 | 297 | }; |
duke@435 | 298 | |
duke@435 | 299 | |
duke@435 | 300 | class ObjectConstant: public ObjectType { |
duke@435 | 301 | private: |
duke@435 | 302 | ciObject* _value; |
duke@435 | 303 | |
duke@435 | 304 | public: |
duke@435 | 305 | ObjectConstant(ciObject* value) { _value = value; } |
duke@435 | 306 | |
duke@435 | 307 | ciObject* value() const { return _value; } |
duke@435 | 308 | |
duke@435 | 309 | virtual bool is_constant() const { return true; } |
duke@435 | 310 | virtual ObjectConstant* as_ObjectConstant() { return this; } |
duke@435 | 311 | virtual ciObject* constant_value() const; |
duke@435 | 312 | }; |
duke@435 | 313 | |
duke@435 | 314 | |
duke@435 | 315 | class ArrayType: public ObjectType { |
duke@435 | 316 | public: |
duke@435 | 317 | virtual ArrayType* as_ArrayType() { return this; } |
duke@435 | 318 | }; |
duke@435 | 319 | |
duke@435 | 320 | |
duke@435 | 321 | class ArrayConstant: public ArrayType { |
duke@435 | 322 | private: |
duke@435 | 323 | ciArray* _value; |
duke@435 | 324 | |
duke@435 | 325 | public: |
duke@435 | 326 | ArrayConstant(ciArray* value) { _value = value; } |
duke@435 | 327 | |
duke@435 | 328 | ciArray* value() const { return _value; } |
duke@435 | 329 | |
duke@435 | 330 | virtual bool is_constant() const { return true; } |
duke@435 | 331 | |
duke@435 | 332 | virtual ArrayConstant* as_ArrayConstant() { return this; } |
duke@435 | 333 | virtual ciObject* constant_value() const; |
duke@435 | 334 | }; |
duke@435 | 335 | |
duke@435 | 336 | |
duke@435 | 337 | class InstanceType: public ObjectType { |
duke@435 | 338 | public: |
duke@435 | 339 | virtual InstanceType* as_InstanceType() { return this; } |
duke@435 | 340 | }; |
duke@435 | 341 | |
duke@435 | 342 | |
duke@435 | 343 | class InstanceConstant: public InstanceType { |
duke@435 | 344 | private: |
duke@435 | 345 | ciInstance* _value; |
duke@435 | 346 | |
duke@435 | 347 | public: |
duke@435 | 348 | InstanceConstant(ciInstance* value) { _value = value; } |
duke@435 | 349 | |
duke@435 | 350 | ciInstance* value() const { return _value; } |
duke@435 | 351 | |
duke@435 | 352 | virtual bool is_constant() const { return true; } |
duke@435 | 353 | |
duke@435 | 354 | virtual InstanceConstant* as_InstanceConstant(){ return this; } |
duke@435 | 355 | virtual ciObject* constant_value() const; |
duke@435 | 356 | }; |
duke@435 | 357 | |
duke@435 | 358 | |
duke@435 | 359 | class ClassType: public ObjectType { |
duke@435 | 360 | public: |
duke@435 | 361 | virtual ClassType* as_ClassType() { return this; } |
duke@435 | 362 | }; |
duke@435 | 363 | |
duke@435 | 364 | |
duke@435 | 365 | class ClassConstant: public ClassType { |
duke@435 | 366 | private: |
duke@435 | 367 | ciInstanceKlass* _value; |
duke@435 | 368 | |
duke@435 | 369 | public: |
duke@435 | 370 | ClassConstant(ciInstanceKlass* value) { _value = value; } |
duke@435 | 371 | |
duke@435 | 372 | ciInstanceKlass* value() const { return _value; } |
duke@435 | 373 | |
duke@435 | 374 | virtual bool is_constant() const { return true; } |
duke@435 | 375 | |
duke@435 | 376 | virtual ClassConstant* as_ClassConstant() { return this; } |
duke@435 | 377 | virtual ciObject* constant_value() const; |
duke@435 | 378 | }; |
duke@435 | 379 | |
duke@435 | 380 | |
duke@435 | 381 | class AddressType: public ValueType { |
duke@435 | 382 | public: |
duke@435 | 383 | AddressType(): ValueType(addressTag, 1) {} |
duke@435 | 384 | virtual ValueType* base() const { return addressType; } |
duke@435 | 385 | virtual const char tchar() const { return 'r'; } |
duke@435 | 386 | virtual const char* name() const { return "address"; } |
duke@435 | 387 | virtual AddressType* as_AddressType() { return this; } |
duke@435 | 388 | }; |
duke@435 | 389 | |
duke@435 | 390 | |
duke@435 | 391 | class AddressConstant: public AddressType { |
duke@435 | 392 | private: |
duke@435 | 393 | jint _value; |
duke@435 | 394 | |
duke@435 | 395 | public: |
duke@435 | 396 | AddressConstant(jint value) { _value = value; } |
duke@435 | 397 | |
duke@435 | 398 | jint value() const { return _value; } |
duke@435 | 399 | |
duke@435 | 400 | virtual bool is_constant() const { return true; } |
duke@435 | 401 | |
duke@435 | 402 | virtual AddressConstant* as_AddressConstant() { return this; } |
duke@435 | 403 | }; |
duke@435 | 404 | |
duke@435 | 405 | |
duke@435 | 406 | class IllegalType: public ValueType { |
duke@435 | 407 | public: |
duke@435 | 408 | IllegalType(): ValueType(illegalTag, -1) {} |
duke@435 | 409 | virtual ValueType* base() const { return illegalType; } |
duke@435 | 410 | virtual const char tchar() const { return ' '; } |
duke@435 | 411 | virtual const char* name() const { return "illegal"; } |
duke@435 | 412 | virtual IllegalType* as_IllegalType() { return this; } |
duke@435 | 413 | }; |
duke@435 | 414 | |
duke@435 | 415 | |
duke@435 | 416 | // conversion between ValueTypes, BasicTypes, and ciConstants |
duke@435 | 417 | ValueType* as_ValueType(BasicType type); |
duke@435 | 418 | ValueType* as_ValueType(ciConstant value); |
duke@435 | 419 | BasicType as_BasicType(ValueType* type); |
duke@435 | 420 | |
duke@435 | 421 | inline ValueType* as_ValueType(ciType* type) { return as_ValueType(type->basic_type()); } |