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: |
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 | |
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_C1_C1_VALUETYPE_HPP |
519 | |