1 /*
2 * Copyright (c) 1999, 2019, 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_C1_C1_VALUETYPE_HPP
26 #define SHARE_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:
ValueType(ValueTag tag,int size)107 ValueType(ValueTag tag, int size): _size(size), _tag(tag) {}
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)
tag() const115 ValueTag tag() const { return _tag; } // the 'canonical' tag (useful for type matching)
size() const116 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
is_constant() const122 virtual bool is_constant() const { return false; }
123
124 // testers
is_void()125 bool is_void() { return tag() == voidTag; }
is_int()126 bool is_int() { return tag() == intTag; }
is_long()127 bool is_long() { return tag() == longTag; }
is_float()128 bool is_float() { return tag() == floatTag; }
is_double()129 bool is_double() { return tag() == doubleTag; }
is_object()130 bool is_object() { return as_ObjectType() != NULL; }
is_array()131 bool is_array() { return as_ArrayType() != NULL; }
is_instance()132 bool is_instance() { return as_InstanceType() != NULL; }
is_class()133 bool is_class() { return as_ClassType() != NULL; }
is_method()134 bool is_method() { return as_MethodType() != NULL; }
is_method_data()135 bool is_method_data() { return as_MethodDataType() != NULL; }
is_address()136 bool is_address() { return as_AddressType() != NULL; }
is_illegal()137 bool is_illegal() { return tag() == illegalTag; }
138
is_int_kind() const139 bool is_int_kind() const { return tag() == intTag || tag() == longTag; }
is_float_kind() const140 bool is_float_kind() const { return tag() == floatTag || tag() == doubleTag; }
is_object_kind() const141 bool is_object_kind() const { return tag() == objectTag; }
142
is_single_word() const143 bool is_single_word() const { return _size == 1; }
is_double_word() const144 bool is_double_word() const { return _size == 2; }
145
146 // casting
as_VoidType()147 virtual VoidType* as_VoidType() { return NULL; }
as_IntType()148 virtual IntType* as_IntType() { return NULL; }
as_LongType()149 virtual LongType* as_LongType() { return NULL; }
as_FloatType()150 virtual FloatType* as_FloatType() { return NULL; }
as_DoubleType()151 virtual DoubleType* as_DoubleType() { return NULL; }
as_ObjectType()152 virtual ObjectType* as_ObjectType() { return NULL; }
as_ArrayType()153 virtual ArrayType* as_ArrayType() { return NULL; }
as_InstanceType()154 virtual InstanceType* as_InstanceType() { return NULL; }
as_ClassType()155 virtual ClassType* as_ClassType() { return NULL; }
as_MetadataType()156 virtual MetadataType* as_MetadataType() { return NULL; }
as_MethodType()157 virtual MethodType* as_MethodType() { return NULL; }
as_MethodDataType()158 virtual MethodDataType* as_MethodDataType() { return NULL; }
as_AddressType()159 virtual AddressType* as_AddressType() { return NULL; }
as_IllegalType()160 virtual IllegalType* as_IllegalType() { return NULL; }
161
as_IntConstant()162 virtual IntConstant* as_IntConstant() { return NULL; }
as_LongConstant()163 virtual LongConstant* as_LongConstant() { return NULL; }
as_FloatConstant()164 virtual FloatConstant* as_FloatConstant() { return NULL; }
as_DoubleConstant()165 virtual DoubleConstant* as_DoubleConstant() { return NULL; }
as_ObjectConstant()166 virtual ObjectConstant* as_ObjectConstant() { return NULL; }
as_InstanceConstant()167 virtual InstanceConstant* as_InstanceConstant(){ return NULL; }
as_ClassConstant()168 virtual ClassConstant* as_ClassConstant() { return NULL; }
as_MethodConstant()169 virtual MethodConstant* as_MethodConstant() { return NULL; }
as_MethodDataConstant()170 virtual MethodDataConstant* as_MethodDataConstant() { return NULL; }
as_ArrayConstant()171 virtual ArrayConstant* as_ArrayConstant() { return NULL; }
as_StableArrayConstant()172 virtual StableArrayConstant* as_StableArrayConstant() { return NULL; }
as_AddressConstant()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
print(outputStream * s=tty)180 void print(outputStream* s = tty) { s->print("%s", name()); }
181 };
182
183
184 class VoidType: public ValueType {
185 public:
VoidType()186 VoidType(): ValueType(voidTag, 0) {}
base() const187 virtual ValueType* base() const { return voidType; }
tchar() const188 virtual const char tchar() const { return 'v'; }
name() const189 virtual const char* name() const { return "void"; }
as_VoidType()190 virtual VoidType* as_VoidType() { return this; }
191 };
192
193
194 class IntType: public ValueType {
195 public:
IntType()196 IntType(): ValueType(intTag, 1) {}
base() const197 virtual ValueType* base() const { return intType; }
tchar() const198 virtual const char tchar() const { return 'i'; }
name() const199 virtual const char* name() const { return "int"; }
as_IntType()200 virtual IntType* as_IntType() { return this; }
201 };
202
203
204 class IntConstant: public IntType {
205 private:
206 jint _value;
207
208 public:
IntConstant(jint value)209 IntConstant(jint value) { _value = value; }
210
value() const211 jint value() const { return _value; }
212
is_constant() const213 virtual bool is_constant() const { return true; }
as_IntConstant()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:
IntInterval(jint beg,jint end)224 IntInterval(jint beg, jint end) {
225 assert(beg <= end, "illegal interval");
226 _beg = beg;
227 _end = end;
228 }
229
beg() const230 jint beg() const { return _beg; }
end() const231 jint end() const { return _end; }
232
is_interval() const233 virtual bool is_interval() const { return true; }
234 };
235
236
237 class LongType: public ValueType {
238 public:
LongType()239 LongType(): ValueType(longTag, 2) {}
base() const240 virtual ValueType* base() const { return longType; }
tchar() const241 virtual const char tchar() const { return 'l'; }
name() const242 virtual const char* name() const { return "long"; }
as_LongType()243 virtual LongType* as_LongType() { return this; }
244 };
245
246
247 class LongConstant: public LongType {
248 private:
249 jlong _value;
250
251 public:
LongConstant(jlong value)252 LongConstant(jlong value) { _value = value; }
253
value() const254 jlong value() const { return _value; }
255
is_constant() const256 virtual bool is_constant() const { return true; }
as_LongConstant()257 virtual LongConstant* as_LongConstant() { return this; }
258 };
259
260
261 class FloatType: public ValueType {
262 public:
FloatType()263 FloatType(): ValueType(floatTag, 1) {}
base() const264 virtual ValueType* base() const { return floatType; }
tchar() const265 virtual const char tchar() const { return 'f'; }
name() const266 virtual const char* name() const { return "float"; }
as_FloatType()267 virtual FloatType* as_FloatType() { return this; }
268 };
269
270
271 class FloatConstant: public FloatType {
272 private:
273 jfloat _value;
274
275 public:
FloatConstant(jfloat value)276 FloatConstant(jfloat value) { _value = value; }
277
value() const278 jfloat value() const { return _value; }
279
is_constant() const280 virtual bool is_constant() const { return true; }
as_FloatConstant()281 virtual FloatConstant* as_FloatConstant() { return this; }
282 };
283
284
285 class DoubleType: public ValueType {
286 public:
DoubleType()287 DoubleType(): ValueType(doubleTag, 2) {}
base() const288 virtual ValueType* base() const { return doubleType; }
tchar() const289 virtual const char tchar() const { return 'd'; }
name() const290 virtual const char* name() const { return "double"; }
as_DoubleType()291 virtual DoubleType* as_DoubleType() { return this; }
292 };
293
294
295 class DoubleConstant: public DoubleType {
296 private:
297 jdouble _value;
298
299 public:
DoubleConstant(jdouble value)300 DoubleConstant(jdouble value) { _value = value; }
301
value() const302 jdouble value() const { return _value; }
303
is_constant() const304 virtual bool is_constant() const { return true; }
as_DoubleConstant()305 virtual DoubleConstant* as_DoubleConstant() { return this; }
306 };
307
308
309 class ObjectType: public ValueType {
310 public:
ObjectType()311 ObjectType(): ValueType(objectTag, 1) {}
base() const312 virtual ValueType* base() const { return objectType; }
tchar() const313 virtual const char tchar() const { return 'a'; }
name() const314 virtual const char* name() const { return "object"; }
as_ObjectType()315 virtual ObjectType* as_ObjectType() { return this; }
constant_value() const316 virtual ciObject* constant_value() const { ShouldNotReachHere(); return NULL; }
exact_type() const317 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:
ObjectConstant(ciObject * value)328 ObjectConstant(ciObject* value) { _value = value; }
329
value() const330 ciObject* value() const { return _value; }
331
is_constant() const332 virtual bool is_constant() const { return true; }
as_ObjectConstant()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:
as_ArrayType()341 virtual ArrayType* as_ArrayType() { return this; }
342 };
343
344
345 class ArrayConstant: public ArrayType {
346 private:
347 ciArray* _value;
348
349 public:
ArrayConstant(ciArray * value)350 ArrayConstant(ciArray* value) { _value = value; }
351
value() const352 ciArray* value() const { return _value; }
353
is_constant() const354 virtual bool is_constant() const { return true; }
as_ArrayConstant()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:
StableArrayConstant(ciArray * value,jint dimension)365 StableArrayConstant(ciArray* value, jint dimension) : ArrayConstant(value) {
366 assert(dimension > 0, "not a stable array");
367 _dimension = dimension;
368 }
369
dimension() const370 jint dimension() const { return _dimension; }
371
as_StableArrayConstant()372 virtual StableArrayConstant* as_StableArrayConstant() { return this; }
373 };
374
375 class InstanceType: public ObjectType {
376 public:
as_InstanceType()377 virtual InstanceType* as_InstanceType() { return this; }
378 };
379
380
381 class InstanceConstant: public InstanceType {
382 private:
383 ciInstance* _value;
384
385 public:
InstanceConstant(ciInstance * value)386 InstanceConstant(ciInstance* value) { _value = value; }
387
value() const388 ciInstance* value() const { return _value; }
389
is_constant() const390 virtual bool is_constant() const { return true; }
as_InstanceConstant()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:
MetadataType()399 MetadataType(): ValueType(metaDataTag, 1) {}
base() const400 virtual ValueType* base() const { return objectType; }
tchar() const401 virtual const char tchar() const { return 'a'; }
name() const402 virtual const char* name() const { return "object"; }
as_MetadataType()403 virtual MetadataType* as_MetadataType() { return this; }
404 bool is_loaded() const;
405 jobject encoding() const;
constant_value() const406 virtual ciMetadata* constant_value() const { ShouldNotReachHere(); return NULL; }
407 };
408
409
410 class ClassType: public MetadataType {
411 public:
as_ClassType()412 virtual ClassType* as_ClassType() { return this; }
413 };
414
415
416 class ClassConstant: public ClassType {
417 private:
418 ciInstanceKlass* _value;
419
420 public:
ClassConstant(ciInstanceKlass * value)421 ClassConstant(ciInstanceKlass* value) { _value = value; }
422
value() const423 ciInstanceKlass* value() const { return _value; }
424
is_constant() const425 virtual bool is_constant() const { return true; }
as_ClassConstant()426 virtual ClassConstant* as_ClassConstant() { return this; }
constant_value() const427 virtual ciMetadata* constant_value() const { return _value; }
428 virtual ciType* exact_type() const;
429 };
430
431
432 class MethodType: public MetadataType {
433 public:
as_MethodType()434 virtual MethodType* as_MethodType() { return this; }
435 };
436
437
438 class MethodConstant: public MethodType {
439 private:
440 ciMethod* _value;
441
442 public:
MethodConstant(ciMethod * value)443 MethodConstant(ciMethod* value) { _value = value; }
444
value() const445 ciMethod* value() const { return _value; }
446
is_constant() const447 virtual bool is_constant() const { return true; }
448
as_MethodConstant()449 virtual MethodConstant* as_MethodConstant() { return this; }
constant_value() const450 virtual ciMetadata* constant_value() const { return _value; }
451 };
452
453
454 class MethodDataType: public MetadataType {
455 public:
as_MethodDataType()456 virtual MethodDataType* as_MethodDataType() { return this; }
457 };
458
459
460 class MethodDataConstant: public MethodDataType {
461 private:
462 ciMethodData* _value;
463
464 public:
MethodDataConstant(ciMethodData * value)465 MethodDataConstant(ciMethodData* value) { _value = value; }
466
value() const467 ciMethodData* value() const { return _value; }
468
is_constant() const469 virtual bool is_constant() const { return true; }
470
as_MethodDataConstant()471 virtual MethodDataConstant* as_MethodDataConstant() { return this; }
constant_value() const472 virtual ciMetadata* constant_value() const { return _value; }
473 };
474
475
476 class AddressType: public ValueType {
477 public:
AddressType()478 AddressType(): ValueType(addressTag, 1) {}
base() const479 virtual ValueType* base() const { return addressType; }
tchar() const480 virtual const char tchar() const { return 'r'; }
name() const481 virtual const char* name() const { return "address"; }
as_AddressType()482 virtual AddressType* as_AddressType() { return this; }
483 };
484
485
486 class AddressConstant: public AddressType {
487 private:
488 jint _value;
489
490 public:
AddressConstant(jint value)491 AddressConstant(jint value) { _value = value; }
492
value() const493 jint value() const { return _value; }
494
is_constant() const495 virtual bool is_constant() const { return true; }
496
as_AddressConstant()497 virtual AddressConstant* as_AddressConstant() { return this; }
498 };
499
500
501 class IllegalType: public ValueType {
502 public:
IllegalType()503 IllegalType(): ValueType(illegalTag, -1) {}
base() const504 virtual ValueType* base() const { return illegalType; }
tchar() const505 virtual const char tchar() const { return ' '; }
name() const506 virtual const char* name() const { return "illegal"; }
as_IllegalType()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
as_ValueType(ciType * type)516 inline ValueType* as_ValueType(ciType* type) { return as_ValueType(type->basic_type()); }
517
518 #endif // SHARE_C1_C1_VALUETYPE_HPP
519