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
33class ValueType;
34class VoidType;
35class IntType;
36class IntConstant;
37class IntInterval;
38class LongType;
39class LongConstant;
40class FloatType;
41class FloatConstant;
42class DoubleType;
43class DoubleConstant;
44class ObjectType;
45class ObjectConstant;
46class ArrayType;
47class ArrayConstant;
48class StableArrayConstant;
49class InstanceType;
50class InstanceConstant;
51class MetadataType;
52class ClassType;
53class ClassConstant;
54class MethodType;
55class MethodConstant;
56class MethodDataType;
57class MethodDataConstant;
58class AddressType;
59class AddressConstant;
60class IllegalType;
61
62
63// predefined types
64extern VoidType* voidType;
65extern IntType* intType;
66extern LongType* longType;
67extern FloatType* floatType;
68extern DoubleType* doubleType;
69extern ObjectType* objectType;
70extern ArrayType* arrayType;
71extern InstanceType* instanceType;
72extern ClassType* classType;
73extern AddressType* addressType;
74extern IllegalType* illegalType;
75
76
77// predefined constants
78extern IntConstant* intZero;
79extern IntConstant* intOne;
80extern ObjectConstant* objectNull;
81
82
83// tags
84enum 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
101class ValueType: public CompilationResourceObj {
102 private:
103 const int _size;
104 const ValueTag _tag;
105 ValueType();
106 protected:
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)
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
184class 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
194class 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
204class 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
218class 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
237class 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
247class 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
261class 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
271class 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
285class 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
295class 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
309class 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
323class 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
339class ArrayType: public ObjectType {
340 public:
341 virtual ArrayType* as_ArrayType() { return this; }
342};
343
344
345class 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
360class 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
375class InstanceType: public ObjectType {
376 public:
377 virtual InstanceType* as_InstanceType() { return this; }
378};
379
380
381class 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
397class 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
410class ClassType: public MetadataType {
411 public:
412 virtual ClassType* as_ClassType() { return this; }
413};
414
415
416class 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
432class MethodType: public MetadataType {
433 public:
434 virtual MethodType* as_MethodType() { return this; }
435};
436
437
438class 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
454class MethodDataType: public MetadataType {
455 public:
456 virtual MethodDataType* as_MethodDataType() { return this; }
457};
458
459
460class 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
476class 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
486class 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
501class 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
512ValueType* as_ValueType(BasicType type);
513ValueType* as_ValueType(ciConstant value);
514BasicType as_BasicType(ValueType* type);
515
516inline ValueType* as_ValueType(ciType* type) { return as_ValueType(type->basic_type()); }
517
518#endif // SHARE_C1_C1_VALUETYPE_HPP
519